-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
FilesystemTasks.cs
85 lines (80 loc) · 2.61 KB
/
FilesystemTasks.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.
using Files.App.Data.Exceptions;
using System.IO;
using System.Runtime.InteropServices;
using Windows.Storage;
namespace Files.App.Utils.Storage
{
public static class FilesystemTasks
{
public static FileSystemStatusCode GetErrorCode(Exception ex, Type? T = null) => (ex, (uint)ex.HResult) switch
{
(UnauthorizedAccessException, _) => FileSystemStatusCode.Unauthorized,
(FileNotFoundException, _) => FileSystemStatusCode.NotFound, // Item was deleted
(PathTooLongException, _) => FileSystemStatusCode.NameTooLong,
(FileAlreadyExistsException, _) => FileSystemStatusCode.AlreadyExists,
(_, 0x8007000F) => FileSystemStatusCode.NotFound, // The system cannot find the drive specified
(_, 0x800700B7) => FileSystemStatusCode.AlreadyExists,
(_, 0x80071779) => FileSystemStatusCode.ReadOnly,
(COMException, _) => FileSystemStatusCode.NotFound, // Item's drive was ejected
(IOException, _) => FileSystemStatusCode.InUse,
(ArgumentException, _) => ToStatusCode(T), // Item was invalid
_ => FileSystemStatusCode.Generic,
};
public async static Task<FilesystemResult> Wrap(Func<Task> wrapped)
{
try
{
await wrapped();
return new FilesystemResult(FileSystemStatusCode.Success);
}
catch (Exception ex)
{
return new FilesystemResult(GetErrorCode(ex));
}
}
public async static Task<FilesystemResult<T>> Wrap<T>(Func<Task<T>> wrapped)
{
try
{
return new FilesystemResult<T>(await wrapped(), FileSystemStatusCode.Success);
}
catch (Exception ex)
{
return new FilesystemResult<T>(default, GetErrorCode(ex, typeof(T)));
}
}
public async static Task<FilesystemResult> OnSuccess<T>(this Task<FilesystemResult<T>> wrapped, Action<T> func)
{
var res = await wrapped;
if (res)
{
func(res.Result);
}
return res;
}
public async static Task<FilesystemResult> OnSuccess<T>(this Task<FilesystemResult<T>> wrapped, Func<T, Task> func)
{
var res = await wrapped;
if (res)
{
return await Wrap(() => func(res.Result));
}
return res;
}
public async static Task<FilesystemResult<V>> OnSuccess<V, T>(this Task<FilesystemResult<T>> wrapped, Func<T, Task<V>> func)
{
var res = await wrapped;
if (res)
{
return await Wrap(() => func(res.Result));
}
return new FilesystemResult<V>(default, res.ErrorCode);
}
private static FileSystemStatusCode ToStatusCode(Type T)
=> T == typeof(StorageFolderWithPath) || typeof(IStorageFolder).IsAssignableFrom(T)
? FileSystemStatusCode.NotAFolder
: FileSystemStatusCode.NotAFile;
}
}