committed by
Max Katz
4 changed files with 106 additions and 86 deletions
@ -0,0 +1,95 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Avalonia.Platform.Storage; |
|||
#pragma warning disable CA1823
|
|||
|
|||
internal class FallbackStorageProvider : IStorageProvider |
|||
{ |
|||
private readonly Func<Task<IStorageProvider?>>[] _factories; |
|||
private readonly List<IStorageProvider> _providers = new(); |
|||
private int _nextProviderFactory = 0; |
|||
|
|||
public FallbackStorageProvider(Func<Task<IStorageProvider?>>[] factories) |
|||
{ |
|||
_factories = factories; |
|||
} |
|||
|
|||
async IAsyncEnumerable<IStorageProvider> GetProviders() |
|||
{ |
|||
foreach (var p in _providers) |
|||
yield return p; |
|||
for (;_nextProviderFactory < _factories.Length;) |
|||
{ |
|||
var p = await _factories[_nextProviderFactory](); |
|||
_nextProviderFactory++; |
|||
if (p != null) |
|||
{ |
|||
_providers.Add(p); |
|||
yield return p; |
|||
} |
|||
} |
|||
} |
|||
|
|||
async Task<IStorageProvider> GetFor(Func<IStorageProvider, bool> filter) |
|||
{ |
|||
await foreach (var p in GetProviders()) |
|||
if (filter(p)) |
|||
return p; |
|||
throw new IOException("Unable to select a suitable storage provider"); |
|||
} |
|||
|
|||
|
|||
// Those should _really_ have been asynchronous,
|
|||
// but this class is expected to fall back to the managed implementation anyway
|
|||
public bool CanOpen => true; |
|||
public bool CanSave => true; |
|||
public bool CanPickFolder => true; |
|||
|
|||
public async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options) |
|||
{ |
|||
return await (await GetFor(p => p.CanOpen)).OpenFilePickerAsync(options); |
|||
} |
|||
|
|||
public async Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options) |
|||
{ |
|||
return await (await GetFor(p => p.CanSave)).SaveFilePickerAsync(options); |
|||
} |
|||
|
|||
|
|||
public async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options) |
|||
{ |
|||
return await (await GetFor(p => p.CanPickFolder)).OpenFolderPickerAsync(options); |
|||
} |
|||
|
|||
async Task<TResult?> FirstNotNull<TArg, TResult>(TArg arg, Func<IStorageProvider, TArg, Task<TResult?>> cb) |
|||
where TResult : class |
|||
{ |
|||
await foreach (var p in GetProviders()) |
|||
{ |
|||
var res = await cb(p, arg); |
|||
if (res != null) |
|||
return res; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public Task<IStorageBookmarkFile?> OpenFileBookmarkAsync(string bookmark) => |
|||
FirstNotNull(bookmark, (p, a) => p.OpenFileBookmarkAsync(a)); |
|||
|
|||
public Task<IStorageBookmarkFolder?> OpenFolderBookmarkAsync(string bookmark) => |
|||
FirstNotNull(bookmark, (p, a) => p.OpenFolderBookmarkAsync(a)); |
|||
|
|||
public Task<IStorageFile?> TryGetFileFromPathAsync(Uri filePath) => |
|||
FirstNotNull(filePath, (p, a) => p.TryGetFileFromPathAsync(filePath)); |
|||
|
|||
public Task<IStorageFolder?> TryGetFolderFromPathAsync(Uri folderPath) |
|||
=> FirstNotNull(folderPath, (p, a) => p.TryGetFolderFromPathAsync(a)); |
|||
|
|||
public Task<IStorageFolder?> TryGetWellKnownFolderAsync(WellKnownFolder wellKnownFolder) => |
|||
FirstNotNull(wellKnownFolder, (p, a) => p.TryGetWellKnownFolderAsync(a)); |
|||
|
|||
} |
|||
@ -1,82 +0,0 @@ |
|||
#nullable enable |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Platform.Storage; |
|||
|
|||
namespace Avalonia.X11.NativeDialogs; |
|||
|
|||
internal class CompositeStorageProvider : IStorageProvider |
|||
{ |
|||
private readonly IEnumerable<Func<Task<IStorageProvider?>>> _factories; |
|||
public CompositeStorageProvider(IEnumerable<Func<Task<IStorageProvider?>>> factories) |
|||
{ |
|||
_factories = factories; |
|||
} |
|||
|
|||
public bool CanOpen => true; |
|||
public bool CanSave => true; |
|||
public bool CanPickFolder => true; |
|||
|
|||
private async Task<IStorageProvider> EnsureStorageProvider() |
|||
{ |
|||
foreach (var factory in _factories) |
|||
{ |
|||
var provider = await factory(); |
|||
if (provider is not null) |
|||
{ |
|||
return provider; |
|||
} |
|||
} |
|||
|
|||
throw new InvalidOperationException("Neither DBus nor GTK are available on the system"); |
|||
} |
|||
|
|||
public async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.OpenFilePickerAsync(options).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.SaveFilePickerAsync(options).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.OpenFolderPickerAsync(options).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageBookmarkFile?> OpenFileBookmarkAsync(string bookmark) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.OpenFileBookmarkAsync(bookmark).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageBookmarkFolder?> OpenFolderBookmarkAsync(string bookmark) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.OpenFolderBookmarkAsync(bookmark).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageFile?> TryGetFileFromPathAsync(Uri filePath) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.TryGetFileFromPathAsync(filePath).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageFolder?> TryGetFolderFromPathAsync(Uri folderPath) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.TryGetFolderFromPathAsync(folderPath).ConfigureAwait(false); |
|||
} |
|||
|
|||
public async Task<IStorageFolder?> TryGetWellKnownFolderAsync(WellKnownFolder wellKnownFolder) |
|||
{ |
|||
var provider = await EnsureStorageProvider().ConfigureAwait(false); |
|||
return await provider.TryGetWellKnownFolderAsync(wellKnownFolder).ConfigureAwait(false); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue