ContentProvider more async
This commit is contained in:
@@ -2,6 +2,6 @@ namespace FileTime.Core.Command;
|
||||
|
||||
public interface ICommandHandler
|
||||
{
|
||||
bool CanHandle(ICommand command);
|
||||
Task<bool> CanHandleAsync(ICommand command);
|
||||
Task ExecuteAsync(ICommand command);
|
||||
}
|
||||
@@ -22,11 +22,11 @@ public interface IContentProvider : IContainer, IOnContainerEnter
|
||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||
ItemInitializationSettings itemInitializationSettings = default);
|
||||
|
||||
NativePath GetNativePath(FullName fullName);
|
||||
ValueTask<NativePath> GetNativePathAsync(FullName fullName);
|
||||
FullName GetFullName(NativePath nativePath);
|
||||
|
||||
Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default);
|
||||
bool CanHandlePath(NativePath path);
|
||||
bool CanHandlePath(FullName path);
|
||||
Task<bool> CanHandlePathAsync(NativePath path);
|
||||
Task<bool> CanHandlePathAsync(FullName path);
|
||||
VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
|
||||
}
|
||||
@@ -15,6 +15,6 @@ public interface ITimelessContentProvider
|
||||
ItemInitializationSettings itemInitializationSettings = default);
|
||||
|
||||
Task<IItem?> GetItemByNativePathAsync(NativePath nativePath, PointInTime? pointInTime = null);
|
||||
FullName? GetFullNameByNativePath(NativePath nativePath);
|
||||
NativePath? GetNativePathByFullName(FullName fullName);
|
||||
ValueTask<FullName?> GetFullNameByNativePathAsync(NativePath nativePath);
|
||||
ValueTask<NativePath?> GetNativePathByFullNameAsync(FullName fullName);
|
||||
}
|
||||
@@ -23,7 +23,10 @@ public class CommandRunner : ICommandRunner
|
||||
}
|
||||
else
|
||||
{
|
||||
var commandHandler = _commandHandlers.Find(c => c.CanHandle(command));
|
||||
var commandHandler = await _commandHandlers
|
||||
.ToAsyncEnumerable()
|
||||
.FirstOrDefaultAwaitAsync(async c => await c.CanHandleAsync(command));
|
||||
|
||||
if (commandHandler != null)
|
||||
{
|
||||
await commandHandler.ExecuteAsync(command);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -11,4 +11,8 @@
|
||||
<ProjectReference Include="..\FileTime.Core.Command\FileTime.Core.Command.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -18,25 +18,30 @@ public class StreamCopyCommandHandler : ICommandHandler
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
}
|
||||
|
||||
public bool CanHandle(ICommand command)
|
||||
public async Task<bool> CanHandleAsync(ICommand command)
|
||||
{
|
||||
if (command is not CopyCommand copyCommand) return false;
|
||||
|
||||
var targetSupportsContentStream =
|
||||
_contentProviderRegistry
|
||||
(await _contentProviderRegistry
|
||||
.ContentProviders
|
||||
.FirstOrDefault(p => p.CanHandlePath(copyCommand.Target!))
|
||||
?.SupportsContentStreams ?? false;
|
||||
.ToAsyncEnumerable()
|
||||
.FirstOrDefaultAwaitAsync(async p => await p.CanHandlePathAsync(copyCommand.Target))
|
||||
)?.SupportsContentStreams ?? false;
|
||||
|
||||
var allSourcesSupportsContentStream =
|
||||
copyCommand
|
||||
(await copyCommand
|
||||
.Sources
|
||||
.Select(s =>
|
||||
.ToAsyncEnumerable()
|
||||
.SelectAwait(s =>
|
||||
_contentProviderRegistry
|
||||
.ContentProviders
|
||||
.FirstOrDefault(p => p.CanHandlePath(s))
|
||||
.ToAsyncEnumerable()
|
||||
.FirstOrDefaultAwaitAsync(async p => await p.CanHandlePathAsync(s))
|
||||
)
|
||||
.All(p => p?.SupportsContentStreams ?? false);
|
||||
.ToListAsync()
|
||||
)
|
||||
.All(p => p?.SupportsContentStreams ?? false);
|
||||
|
||||
return targetSupportsContentStream && allSourcesSupportsContentStream;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class ContentProviderBase : IContentProvider
|
||||
bool forceResolve = false,
|
||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||
ItemInitializationSettings itemInitializationSettings = default)
|
||||
=> await GetItemByNativePathAsync(GetNativePath(fullName), pointInTime, forceResolve, forceResolvePathType,
|
||||
=> await GetItemByNativePathAsync(await GetNativePathAsync(fullName), pointInTime, forceResolve, forceResolvePathType,
|
||||
itemInitializationSettings);
|
||||
|
||||
public abstract Task<IItem> GetItemByNativePathAsync(NativePath nativePath,
|
||||
@@ -81,15 +81,18 @@ public abstract class ContentProviderBase : IContentProvider
|
||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||
ItemInitializationSettings itemInitializationSettings = default);
|
||||
|
||||
public abstract NativePath GetNativePath(FullName fullName);
|
||||
public abstract ValueTask<NativePath> GetNativePathAsync(FullName fullName);
|
||||
public abstract FullName GetFullName(NativePath nativePath);
|
||||
|
||||
public abstract Task<byte[]?> GetContentAsync(IElement element,
|
||||
int? maxLength = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
public abstract bool CanHandlePath(NativePath path);
|
||||
public bool CanHandlePath(FullName path) => CanHandlePath(GetNativePath(path));
|
||||
public abstract Task<bool> CanHandlePathAsync(NativePath path);
|
||||
public async Task<bool> CanHandlePathAsync(FullName path)
|
||||
=> path.Path.TrimEnd(Constants.SeparatorChar) == Name
|
||||
|| await CanHandlePathAsync(await GetNativePathAsync(path));
|
||||
|
||||
public abstract VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
|
||||
|
||||
public IItem WithParent(AbsolutePath parent) => this;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class RootContentProvider : IRootContentProvider
|
||||
pointInTime
|
||||
) ?? throw new FileNotFoundException();
|
||||
|
||||
public NativePath GetNativePath(FullName fullName) => throw new NotImplementedException();
|
||||
public ValueTask<NativePath> GetNativePathAsync(FullName fullName) => throw new NotImplementedException();
|
||||
|
||||
public FullName GetFullName(NativePath nativePath) => throw new NotImplementedException();
|
||||
|
||||
@@ -82,9 +82,9 @@ public class RootContentProvider : IRootContentProvider
|
||||
int? maxLength = null,
|
||||
CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
public bool CanHandlePath(NativePath path) => throw new NotImplementedException();
|
||||
public Task<bool> CanHandlePathAsync(NativePath path) => throw new NotImplementedException();
|
||||
|
||||
public bool CanHandlePath(FullName path) => throw new NotImplementedException();
|
||||
public Task<bool> CanHandlePathAsync(FullName path) => throw new NotImplementedException();
|
||||
public VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
|
||||
|
||||
public IItem WithParent(AbsolutePath parent) => this;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class TimelessContentProvider : ITimelessContentProvider
|
||||
{
|
||||
foreach (var contentProvider in _contentProviderRegistry.ContentProviders)
|
||||
{
|
||||
if (!contentProvider.CanHandlePath(nativePath)) continue;
|
||||
if (!await contentProvider.CanHandlePathAsync(nativePath)) continue;
|
||||
|
||||
return await contentProvider.GetItemByNativePathAsync(nativePath, pointInTime ?? PointInTime.Present);
|
||||
}
|
||||
@@ -53,11 +53,11 @@ public class TimelessContentProvider : ITimelessContentProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
public FullName? GetFullNameByNativePath(NativePath nativePath)
|
||||
public async ValueTask<FullName?> GetFullNameByNativePathAsync(NativePath nativePath)
|
||||
{
|
||||
foreach (var contentProvider in _contentProviderRegistry.ContentProviders)
|
||||
{
|
||||
if (!contentProvider.CanHandlePath(nativePath)) continue;
|
||||
if (!await contentProvider.CanHandlePathAsync(nativePath)) continue;
|
||||
|
||||
return contentProvider.GetFullName(nativePath);
|
||||
}
|
||||
@@ -65,13 +65,13 @@ public class TimelessContentProvider : ITimelessContentProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
public NativePath? GetNativePathByFullName(FullName fullName)
|
||||
public async ValueTask<NativePath?> GetNativePathByFullNameAsync(FullName fullName)
|
||||
{
|
||||
foreach (var contentProvider in _contentProviderRegistry.ContentProviders)
|
||||
{
|
||||
if (!contentProvider.CanHandlePath(fullName)) continue;
|
||||
if (!await contentProvider.CanHandlePathAsync(fullName)) continue;
|
||||
|
||||
return contentProvider.GetNativePath(fullName);
|
||||
return await contentProvider.GetNativePathAsync(fullName);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user