Use primary constructors

This commit is contained in:
2023-10-31 14:18:21 +01:00
parent 2a7aa6bf3a
commit 17466de219
25 changed files with 132 additions and 339 deletions

View File

@@ -3,9 +3,9 @@ using PropertyChanged.SourceGenerator;
namespace FileTime.Core.Interactions;
public partial class OptionsInputElement<T> : InputElementBase, IOptionsInputElement, INotifyPropertyChanged
public partial class OptionsInputElement<T>(string label, IEnumerable<OptionElement<T>> options) : InputElementBase(label, InputType.Options), IOptionsInputElement, INotifyPropertyChanged
{
public IReadOnlyCollection<OptionElement<T>> Options { get; }
public IReadOnlyCollection<OptionElement<T>> Options { get; } = Enumerable.ToList<OptionElement<T>>(options);
[Notify] private T? _value;
@@ -26,9 +26,4 @@ public partial class OptionsInputElement<T> : InputElementBase, IOptionsInputEle
}
}
}
public OptionsInputElement(string label, IEnumerable<OptionElement<T>> options) : base(label, InputType.Options)
{
Options = options.ToList();
}
}

View File

@@ -1,8 +1,7 @@
namespace GeneralInputKey;
public class GeneralKeyEventArgs
public class GeneralKeyEventArgs(Action<bool>? handledChanged = null)
{
private readonly Action<bool>? _handledChanged;
private bool _handled;
public required Keys? Key { get; init; }
public required char KeyChar { get; init; }
@@ -16,13 +15,8 @@ public class GeneralKeyEventArgs
if (_handled != value)
{
_handled = value;
_handledChanged?.Invoke(value);
handledChanged?.Invoke(value);
}
}
}
public GeneralKeyEventArgs(Action<bool>? handledChanged = null)
{
_handledChanged = handledChanged;
}
}

View File

@@ -5,9 +5,8 @@ using TerminalUI.TextFormat;
namespace TerminalUI.Examples.Controls;
public class ProgressBarExamples
public class ProgressBarExamples(IApplicationContext applicationContext)
{
private readonly IApplicationContext _applicationContext;
private static readonly IConsoleDriver _driver;
static ProgressBarExamples()
@@ -16,11 +15,6 @@ public class ProgressBarExamples
_driver.Init();
}
public ProgressBarExamples(IApplicationContext applicationContext)
{
_applicationContext = applicationContext;
}
public void LoadingExample()
{
var progressBar = CreateProgressBar<object>(0);
@@ -46,7 +40,7 @@ public class ProgressBarExamples
{
Value = percent,
Attached = true,
ApplicationContext = _applicationContext
ApplicationContext = applicationContext
};
private void RenderProgressBar<T>(ProgressBar<T> progressBar, Position position)

View File

@@ -6,13 +6,7 @@ namespace TerminalUI.Tests.Models;
public sealed partial class TestViewModel : INotifyPropertyChanged
{
[Notify] private List<TestNestedCollectionItem> _items;
[Notify] private string _text;
public TestViewModel()
{
_text = "Initial text";
_items = new List<TestNestedCollectionItem>
[Notify] private List<TestNestedCollectionItem> _items = new()
{
TestNestedCollectionItem.Create(
3,
@@ -23,7 +17,7 @@ public sealed partial class TestViewModel : INotifyPropertyChanged
new()
)
};
}
[Notify] private string _text = "Initial text";
public event PropertyChangedEventHandler? PropertyChanged;

View File

@@ -5,12 +5,12 @@ using TerminalUI.Styling;
namespace TerminalUI;
public class ApplicationContext : IApplicationContext
public class ApplicationContext(IServiceProvider serviceProvider) : IApplicationContext
{
private readonly Lazy<IConsoleDriver> _consoleDriver;
private readonly Lazy<IFocusManager> _focusManager;
private readonly Lazy<ILoggerFactory?> _loggerFactory;
private readonly Lazy<IRenderEngine> _renderEngine;
private readonly Lazy<IConsoleDriver> _consoleDriver = new Lazy<IConsoleDriver>(serviceProvider.GetRequiredService<IConsoleDriver>);
private readonly Lazy<IFocusManager> _focusManager = new Lazy<IFocusManager>(serviceProvider.GetRequiredService<IFocusManager>);
private readonly Lazy<ILoggerFactory?> _loggerFactory = new Lazy<ILoggerFactory?>(serviceProvider.GetService<ILoggerFactory?>);
private readonly Lazy<IRenderEngine> _renderEngine = new Lazy<IRenderEngine>(serviceProvider.GetRequiredService<IRenderEngine>);
public IConsoleDriver ConsoleDriver => _consoleDriver.Value;
public IFocusManager FocusManager => _focusManager.Value;
@@ -20,12 +20,4 @@ public class ApplicationContext : IApplicationContext
public bool IsRunning { get; set; }
public char EmptyCharacter { get; init; } = ' ';
public bool SupportUtf8Output { get; set; } = true;
public ApplicationContext(IServiceProvider serviceProvider)
{
_consoleDriver = new Lazy<IConsoleDriver>(serviceProvider.GetRequiredService<IConsoleDriver>);
_focusManager = new Lazy<IFocusManager>(serviceProvider.GetRequiredService<IFocusManager>);
_loggerFactory = new Lazy<ILoggerFactory?>(serviceProvider.GetService<ILoggerFactory?>);
_renderEngine = new Lazy<IRenderEngine>(serviceProvider.GetRequiredService<IRenderEngine>);
}
}

View File

@@ -7,31 +7,24 @@ namespace TerminalUI.Controls;
public record ChildWithDataContextMapper<TSourceDataContext, TTargetDataContext>(IView<TTargetDataContext> Child, Func<TSourceDataContext?, TTargetDataContext?> DataContextMapper);
public record ChildWithDataContextBinding<TSourceDataContext, TTargetDataContext>(IView<TTargetDataContext> Child, Expression<Func<TSourceDataContext?, TTargetDataContext?>> DataContextExpression);
public class ChildInitializer<T> : IEnumerable<IView>
public class ChildInitializer<T>(IChildContainer<T> childContainer) : IEnumerable<IView>
{
private readonly IChildContainer<T> _childContainer;
public ChildInitializer(IChildContainer<T> childContainer)
{
_childContainer = childContainer;
}
public void Add(IView<T> item) => _childContainer.AddChild(item);
public void Add(IView<T> item) => childContainer.AddChild(item);
public void Add<TDataContext>(ChildWithDataContextMapper<T, TDataContext> item)
=> _childContainer.AddChild(item.Child, item.DataContextMapper);
=> childContainer.AddChild(item.Child, item.DataContextMapper);
public void Add<TDataContext>(ChildWithDataContextBinding<T, TDataContext> item)
{
item.Child.Bind(
_childContainer,
childContainer,
item.DataContextExpression,
c => c.DataContext
);
_childContainer.AddChild(item.Child);
childContainer.AddChild(item.Child);
}
public IEnumerator<IView> GetEnumerator() => _childContainer.Children.GetEnumerator();
public IEnumerator<IView> GetEnumerator() => childContainer.Children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

View File

@@ -2,37 +2,30 @@
namespace TerminalUI;
public class EventLoop : IEventLoop
public class EventLoop(IApplicationContext applicationContext,
ILogger<EventLoop> logger)
: IEventLoop
{
private readonly IApplicationContext _applicationContext;
private readonly ILogger<EventLoop> _logger;
private readonly ILogger<EventLoop> _logger = logger;
private readonly List<Action> _initializers = new();
private readonly List<Action> _permanentQueue = new();
private readonly List<Action> _finalizers = new();
public int ThreadId { get; set; } = -1;
public EventLoop(
IApplicationContext applicationContext,
ILogger<EventLoop> logger)
{
_applicationContext = applicationContext;
_logger = logger;
}
public void AddToPermanentQueue(Action action) => _permanentQueue.Add(action);
public void AddInitializer(Action action) => _initializers.Add(action);
public void AddFinalizer(Action action) => _finalizers.Add(action);
public void Run()
{
_applicationContext.IsRunning = true;
applicationContext.IsRunning = true;
ThreadId = Thread.CurrentThread.ManagedThreadId;
foreach (var initializer in _initializers)
{
initializer();
}
while (_applicationContext.IsRunning)
while (applicationContext.IsRunning)
{
ProcessQueues();
Thread.Sleep(10);

View File

@@ -5,9 +5,8 @@ using TerminalUI.Traits;
namespace TerminalUI;
public class FocusManager : IFocusManager
public class FocusManager(IRenderEngine renderEngine) : IFocusManager
{
private readonly IRenderEngine _renderEngine;
private IFocusable? _focused;
private DateTime _focusLostCandidateTime = DateTime.MinValue;
@@ -52,11 +51,6 @@ public class FocusManager : IFocusManager
private set => _focused = value;
}
public FocusManager(IRenderEngine renderEngine)
{
_renderEngine = renderEngine;
}
public void SetFocus(IFocusable focusable) => Focused = focusable;
public void UnFocus(IFocusable focusable)
@@ -127,8 +121,8 @@ public class FocusManager : IFocusManager
if (element is null) return;
_renderEngine.RequestRerender(element);
_renderEngine.RequestRerender(view);
renderEngine.RequestRerender(element);
renderEngine.RequestRerender(view);
Focused = element;
}

View File

@@ -1,13 +1,7 @@
namespace TerminalUI.Models;
public readonly ref struct Option<T>
public readonly ref struct Option<T>(T value, bool isSome)
{
public readonly T Value;
public readonly bool IsSome;
public Option(T value, bool isSome)
{
Value = value;
IsSome = isSome;
}
public readonly T Value = value;
public readonly bool IsSome = isSome;
}

View File

@@ -1,20 +1,12 @@
namespace TerminalUI.Models;
public readonly struct SelectiveChar
public readonly struct SelectiveChar(char utf8Char, char asciiChar)
{
public readonly char Utf8Char;
public readonly char AsciiChar;
public readonly char Utf8Char = utf8Char;
public readonly char AsciiChar = asciiChar;
public SelectiveChar(char c)
public SelectiveChar(char c) : this(c, c)
{
Utf8Char = c;
AsciiChar = c;
}
public SelectiveChar(char utf8Char, char asciiChar)
{
Utf8Char = utf8Char;
AsciiChar = asciiChar;
}
public char GetChar(bool enableUtf8) => enableUtf8 ? Utf8Char : AsciiChar;

View File

@@ -1,11 +1,6 @@
namespace TerminalUI.TextFormat;
public readonly struct TextFormatContext
public readonly struct TextFormatContext(bool supportsAnsi)
{
public readonly bool SupportsAnsi;
public TextFormatContext(bool supportsAnsi)
{
SupportsAnsi = supportsAnsi;
}
public readonly bool SupportsAnsi = supportsAnsi;
}

View File

@@ -6,29 +6,15 @@ using Microsoft.Extensions.Options;
namespace FileTime.Server.Web;
public class PortWriterService : IHostedService
{
private readonly IServer _server;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly IOptions<PortWriterConfiguration> _configuration;
private readonly ILogger<PortWriterService> _logger;
public PortWriterService(
IServer server,
public class PortWriterService(IServer server,
IHostApplicationLifetime hostApplicationLifetime,
IOptions<PortWriterConfiguration> configuration,
ILogger<PortWriterService> logger)
: IHostedService
{
_server = server;
_hostApplicationLifetime = hostApplicationLifetime;
_configuration = configuration;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_hostApplicationLifetime.ApplicationStarted.Register(WritePort);
hostApplicationLifetime.ApplicationStarted.Register(WritePort);
return Task.CompletedTask;
}
@@ -37,28 +23,28 @@ public class PortWriterService : IHostedService
{
try
{
var filename = _configuration.Value.Filename;
var filename = configuration.Value.Filename;
if (filename is null)
{
_logger.LogWarning("Could not save port to file as there were no file name given");
logger.LogWarning("Could not save port to file as there were no file name given");
return;
}
var address = GetAddress();
if (address is null)
{
_logger.LogError("Could not get address");
logger.LogError("Could not get address");
return;
}
var couldParsePort = int.TryParse(address.Split(':').LastOrDefault(), out var port);
if (!couldParsePort)
{
_logger.LogError("Could not parse port from address {Address}", address);
logger.LogError("Could not parse port from address {Address}", address);
return;
}
_logger.LogInformation("Writing port to {PortFile}", filename);
logger.LogInformation("Writing port to {PortFile}", filename);
using var tempFileStream = File.CreateText(filename);
tempFileStream.Write(port.ToString());
@@ -67,24 +53,24 @@ public class PortWriterService : IHostedService
await Task.Delay(5000);
try
{
_logger.LogInformation("Deleting port file {PortFile}", filename);
logger.LogInformation("Deleting port file {PortFile}", filename);
File.Delete(filename);
}
catch (Exception e)
{
_logger.LogError(e, "Error while deleting port file {PortFile}", filename);
logger.LogError(e, "Error while deleting port file {PortFile}", filename);
}
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Could not save port to file");
logger.LogError(ex, "Could not save port to file");
}
}
private string? GetAddress()
{
var features = _server.Features;
var features = server.Features;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses?.Addresses.FirstOrDefault();
return address;

View File

@@ -5,37 +5,26 @@ using SharpCompress.Common;
namespace FileTime.Tools.Compression;
public class CompressOperation<TEntry, TVolume> : ICompressOperation
public class CompressOperation<TEntry, TVolume>(IContentAccessorFactory contentAccessorFactory,
AbstractWritableArchive<TEntry, TVolume> archive,
Action<Stream> saveTo)
: ICompressOperation
where TEntry : IArchiveEntry
where TVolume : IVolume
{
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly AbstractWritableArchive<TEntry, TVolume> _archive;
private readonly Action<Stream> _saveTo;
private bool _disposed;
public CompressOperation(
IContentAccessorFactory contentAccessorFactory,
AbstractWritableArchive<TEntry, TVolume> archive,
Action<Stream> saveTo
)
{
_contentAccessorFactory = contentAccessorFactory;
_archive = archive;
_saveTo = saveTo;
}
public async Task<IEnumerable<IDisposable>> CompressElement(IElement element, string key)
{
var contentReader = await _contentAccessorFactory.GetContentReaderFactory(element.Provider).CreateContentReaderAsync(element);
var contentReader = await contentAccessorFactory.GetContentReaderFactory(element.Provider).CreateContentReaderAsync(element);
var contentReaderStream = contentReader.GetStream();
_archive.AddEntry(key, contentReaderStream);
archive.AddEntry(key, contentReaderStream);
return new IDisposable[] {contentReader, contentReaderStream};
}
public void SaveTo(Stream stream)
=> _saveTo(stream);
=> saveTo(stream);
~CompressOperation()
{
@@ -54,7 +43,7 @@ public class CompressOperation<TEntry, TVolume> : ICompressOperation
{
if (disposing)
{
_archive.Dispose();
archive.Dispose();
}
}

View File

@@ -6,31 +6,18 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.Compression.Compress;
public class CompressCommandFactory : ITransportationCommandFactory<CompressCommand>
{
private readonly IUserCommunicationService _userCommunicationService;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
public CompressCommandFactory(
IUserCommunicationService userCommunicationService,
public class CompressCommandFactory(IUserCommunicationService userCommunicationService,
ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory,
ICommandSchedulerNotifier commandSchedulerNotifier)
: ITransportationCommandFactory<CompressCommand>
{
_userCommunicationService = userCommunicationService;
_timelessContentProvider = timelessContentProvider;
_contentAccessorFactory = contentAccessorFactory;
_commandSchedulerNotifier = commandSchedulerNotifier;
}
public CompressCommand GenerateCommand(IReadOnlyCollection<FullName> sources, TransportMode mode, FullName targetFullName)
=> new(
_userCommunicationService,
_timelessContentProvider,
_contentAccessorFactory,
_commandSchedulerNotifier,
userCommunicationService,
timelessContentProvider,
contentAccessorFactory,
commandSchedulerNotifier,
sources,
mode,
targetFullName

View File

@@ -5,24 +5,14 @@ using SharpCompress.Archives;
namespace FileTime.Tools.Compression.ContentProvider;
public sealed class CompressedContentProvider : SubContentProviderBase, ICompressedContentProvider
{
private readonly ITimelessContentProvider _timelessContentProvider;
public CompressedContentProvider(
ITimelessContentProvider timelessContentProvider,
public sealed class CompressedContentProvider(ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory,
IContentProvider parentContentProvider
)
: base(
timelessContentProvider,
IContentProvider parentContentProvider)
: SubContentProviderBase(timelessContentProvider,
contentAccessorFactory,
parentContentProvider,
"compression")
"compression"), ICompressedContentProvider
{
_timelessContentProvider = timelessContentProvider;
}
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
{
var parentElementContext = await GetParentElementReaderAsync(element);
@@ -43,7 +33,7 @@ public sealed class CompressedContentProvider : SubContentProviderBase, ICompres
public override async ValueTask<VolumeSizeInfo?> GetVolumeSizeInfoAsync(FullName path)
{
var item = await GetItemByFullNameAsync(path, _timelessContentProvider.CurrentPointInTime.Value!);
var item = await GetItemByFullNameAsync(path, timelessContentProvider.CurrentPointInTime.Value!);
var parentElement = await GetParentElementAsync(item);
return new VolumeSizeInfo(parentElement.Size, 0);
}

View File

@@ -3,19 +3,10 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.Compression.ContentProvider;
public sealed class CompressedContentProviderFactory : ICompressedContentProviderFactory
{
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IContentAccessorFactory _contentAccessorFactory;
public CompressedContentProviderFactory(
ITimelessContentProvider timelessContentProvider,
public sealed class CompressedContentProviderFactory(ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory)
: ICompressedContentProviderFactory
{
_timelessContentProvider = timelessContentProvider;
_contentAccessorFactory = contentAccessorFactory;
}
public ICompressedContentProvider Create(IContentProvider parentContentProvider)
=> new CompressedContentProvider(_timelessContentProvider, _contentAccessorFactory, parentContentProvider);
=> new CompressedContentProvider(timelessContentProvider, contentAccessorFactory, parentContentProvider);
}

View File

@@ -3,21 +3,14 @@ using SharpCompress.Archives;
namespace FileTime.Tools.Compression.ContentProvider;
public sealed class CompressedContentReader : IContentReader
public sealed class CompressedContentReader(IArchiveEntry entry, IDisposable[] disposables) : IContentReader
{
private readonly IDisposable[] _disposables;
private readonly Stream _stream;
public CompressedContentReader(IArchiveEntry entry, IDisposable[] disposables)
{
_disposables = disposables;
_stream = entry.OpenEntryStream();
}
private readonly Stream _stream = entry.OpenEntryStream();
public void Dispose()
{
_stream.Dispose();
foreach (var disposable in _disposables)
foreach (var disposable in disposables)
{
disposable.Dispose();
}

View File

@@ -4,13 +4,8 @@ using SharpCompress.Archives;
namespace FileTime.Tools.Compression.ContentProvider;
public sealed class CompressedContentReaderFactory : SubContentReaderBase<CompressedContentProvider>
public sealed class CompressedContentReaderFactory(IContentAccessorFactory contentAccessorFactory) : SubContentReaderBase<CompressedContentProvider>(contentAccessorFactory)
{
public CompressedContentReaderFactory(IContentAccessorFactory contentAccessorFactory)
: base(contentAccessorFactory)
{
}
public override async Task<IContentReader> CreateContentReaderAsync(IElement element)
{
if (element.Provider is not CompressedContentProvider provider)

View File

@@ -8,25 +8,13 @@ using IContainer = FileTime.Core.Models.IContainer;
namespace FileTime.Tools.Compression.ContentProvider;
public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
public sealed class CompressedSubContentProvider(IContentAccessorFactory contentAccessorFactory,
ICompressedContentProviderFactory compressedContentProviderFactory,
ITimelessContentProvider timelessContentProvider)
: ICompressedSubContentProvider
{
private static readonly string[] SupportedExtensions = {".zip", ".gz", ".7z"};
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ICompressedContentProviderFactory _compressedContentProviderFactory;
private readonly ITimelessContentProvider _timelessContentProvider;
public CompressedSubContentProvider(
IContentAccessorFactory contentAccessorFactory,
ICompressedContentProviderFactory compressedContentProviderFactory,
ITimelessContentProvider timelessContentProvider
)
{
_contentAccessorFactory = contentAccessorFactory;
_compressedContentProviderFactory = compressedContentProviderFactory;
_timelessContentProvider = timelessContentProvider;
}
public Task<bool> CanHandleAsync(IElement parentElement)
=> Task.FromResult(
parentElement.NativePath?.Path is { } path
@@ -40,7 +28,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
ItemInitializationSettings itemInitializationSettings = default)
{
var parentContentReader = await _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider).CreateContentReaderAsync(parentElement);
var parentContentReader = await contentAccessorFactory.GetContentReaderFactory(parentElement.Provider).CreateContentReaderAsync(parentElement);
var parentContentReaderStream = parentContentReader.GetStream();
var archive = ArchiveFactory.Open(parentContentReaderStream);
var disposables = new IDisposable[] {parentContentReader, parentContentReaderStream, archive};
@@ -117,7 +105,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
}
var parent = new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
parentElement.PointInTime,
childFullName.GetParent()!,
AbsolutePathType.Container
@@ -183,7 +171,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
SupportsDelete.False,
false,
"",
_compressedContentProviderFactory.Create(parentElement.Provider),
compressedContentProviderFactory.Create(parentElement.Provider),
false,
parentElement.PointInTime,
exceptions,
@@ -246,7 +234,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
addedContainers.Add(itemName);
children.Add(new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
pointInTime,
container.FullName.GetChild(itemName),
AbsolutePathType.Container)
@@ -256,7 +244,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
{
//Element
children.Add(new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
pointInTime,
container.FullName.GetChild(itemName),
AbsolutePathType.Element)
@@ -290,7 +278,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
false,
"",
size,
_compressedContentProviderFactory.Create(parentElement.Provider),
compressedContentProviderFactory.Create(parentElement.Provider),
parentElement.PointInTime,
exceptions,
new ReadOnlyExtensionCollection(new ExtensionCollection())

View File

@@ -5,27 +5,16 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.Compression.Decompress;
public class DecompressCommandFactory : ITransportationCommandFactory<DecompressCommand>
{
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
public DecompressCommandFactory(
ITimelessContentProvider timelessContentProvider,
public class DecompressCommandFactory(ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory,
ICommandSchedulerNotifier commandSchedulerNotifier)
: ITransportationCommandFactory<DecompressCommand>
{
_timelessContentProvider = timelessContentProvider;
_contentAccessorFactory = contentAccessorFactory;
_commandSchedulerNotifier = commandSchedulerNotifier;
}
public DecompressCommand GenerateCommand(IReadOnlyCollection<FullName> sources, TransportMode mode, FullName targetFullName)
=> new(
_timelessContentProvider,
_contentAccessorFactory,
_commandSchedulerNotifier,
timelessContentProvider,
contentAccessorFactory,
commandSchedulerNotifier,
sources,
mode,
targetFullName);

View File

@@ -5,24 +5,14 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.VirtualDiskSources;
public sealed class VirtualDiskContentProvider : SubContentProviderBase, IVirtualDiskContentProvider
{
private readonly ITimelessContentProvider _timelessContentProvider;
public VirtualDiskContentProvider(
ITimelessContentProvider timelessContentProvider,
public sealed class VirtualDiskContentProvider(ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory,
IContentProvider parentContentProvider)
: base(
timelessContentProvider,
: SubContentProviderBase(timelessContentProvider,
contentAccessorFactory,
parentContentProvider,
"virtual-disk"
)
"virtual-disk"), IVirtualDiskContentProvider
{
_timelessContentProvider = timelessContentProvider;
}
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
{
var parentElementContext = await GetParentElementReaderAsync(element);
@@ -44,7 +34,7 @@ public sealed class VirtualDiskContentProvider : SubContentProviderBase, IVirtua
public override async ValueTask<VolumeSizeInfo?> GetVolumeSizeInfoAsync(FullName path)
{
var item = await GetItemByFullNameAsync(path, _timelessContentProvider.CurrentPointInTime.Value!);
var item = await GetItemByFullNameAsync(path, timelessContentProvider.CurrentPointInTime.Value!);
var parentElement = await GetParentElementAsync(item);
return new VolumeSizeInfo(parentElement.Size, 0);
}

View File

@@ -3,19 +3,10 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.VirtualDiskSources;
public sealed class VirtualDiskContentProviderFactory : IVirtualDiskContentProviderFactory
{
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IContentAccessorFactory _contentAccessorFactory;
public VirtualDiskContentProviderFactory(
ITimelessContentProvider timelessContentProvider,
public sealed class VirtualDiskContentProviderFactory(ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory)
: IVirtualDiskContentProviderFactory
{
_timelessContentProvider = timelessContentProvider;
_contentAccessorFactory = contentAccessorFactory;
}
public IVirtualDiskContentProvider Create(IContentProvider parentContentProvider)
=> new VirtualDiskContentProvider(_timelessContentProvider, _contentAccessorFactory, parentContentProvider);
=> new VirtualDiskContentProvider(timelessContentProvider, contentAccessorFactory, parentContentProvider);
}

View File

@@ -2,23 +2,14 @@
namespace FileTime.Tools.VirtualDiskSources;
public sealed class VirtualDiskContentReader : IContentReader
public sealed class VirtualDiskContentReader(Stream stream, ICollection<IDisposable> disposables) : IContentReader
{
private readonly Stream _stream;
private readonly ICollection<IDisposable> _disposables;
public VirtualDiskContentReader(Stream stream, ICollection<IDisposable> disposables)
{
_stream = stream;
_disposables = disposables;
}
public Stream GetStream() => _stream;
public Stream GetStream() => stream;
public void Dispose()
{
_stream.Dispose();
foreach (var disposable in _disposables)
stream.Dispose();
foreach (var disposable in disposables)
{
disposable.Dispose();
}

View File

@@ -4,13 +4,8 @@ using FileTime.Core.Models;
namespace FileTime.Tools.VirtualDiskSources;
public sealed class VirtualDiskContentReaderFactory : SubContentReaderBase<VirtualDiskContentProvider>
public sealed class VirtualDiskContentReaderFactory(IContentAccessorFactory contentAccessorFactory) : SubContentReaderBase<VirtualDiskContentProvider>(contentAccessorFactory)
{
public VirtualDiskContentReaderFactory(IContentAccessorFactory contentAccessorFactory)
: base(contentAccessorFactory)
{
}
public override async Task<IContentReader> CreateContentReaderAsync(IElement element)
{
if (element.Provider is not VirtualDiskContentProvider provider)

View File

@@ -8,23 +8,11 @@ using FileTime.Core.Timeline;
namespace FileTime.Tools.VirtualDiskSources;
public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
{
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IVirtualDiskContentProviderFactory _virtualDiskContentProviderFactory;
public VirtualDiskSubContentProvider(
IContentAccessorFactory contentAccessorFactory,
public sealed class VirtualDiskSubContentProvider(IContentAccessorFactory contentAccessorFactory,
ITimelessContentProvider timelessContentProvider,
IVirtualDiskContentProviderFactory virtualDiskContentProviderFactory
)
IVirtualDiskContentProviderFactory virtualDiskContentProviderFactory)
: IVirtualDiskSubContentProvider
{
_contentAccessorFactory = contentAccessorFactory;
_timelessContentProvider = timelessContentProvider;
_virtualDiskContentProviderFactory = virtualDiskContentProviderFactory;
}
public Task<bool> CanHandleAsync(IElement parentElement)
=> Task.FromResult(parentElement.NativePath?.Path.EndsWith(".iso", StringComparison.OrdinalIgnoreCase) ?? false);
@@ -35,7 +23,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
ItemInitializationSettings itemInitializationSettings = default)
{
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
var contentReaderFactory = contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
await using var readerStream = reader.GetStream();
@@ -80,7 +68,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
var childNativePath = new NativePath(childNativePathBase);
var parent = new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
pointInTime,
childFullName.GetParent()!,
AbsolutePathType.Container
@@ -152,7 +140,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
SupportsDelete.False,
false,
FormatAttributes(sourceContainer.Attributes),
_virtualDiskContentProviderFactory.Create(parentContentProvider),
virtualDiskContentProviderFactory.Create(parentContentProvider),
false,
pointInTime,
exceptions,
@@ -191,7 +179,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
foreach (var discDirectoryInfo in sourceContainer.GetDirectories())
{
children.Add(new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
pointInTime,
container.FullName.GetChild(discDirectoryInfo.Name),
AbsolutePathType.Container)
@@ -201,7 +189,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
foreach (var fileInfo in sourceContainer.GetFiles())
{
children.Add(new AbsolutePath(
_timelessContentProvider,
timelessContentProvider,
pointInTime,
container.FullName.GetChild(fileInfo.Name),
AbsolutePathType.Element)
@@ -230,7 +218,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
false,
FormatAttributes(childElement.Attributes),
childElement.Length,
_virtualDiskContentProviderFactory.Create(parentContentProvider),
virtualDiskContentProviderFactory.Create(parentContentProvider),
pointInTime,
new ObservableCollection<Exception>(),
new ReadOnlyExtensionCollection(new ExtensionCollection())