Skip to content

Commit ab47a4d

Browse files
CopilotKSemenenko
andcommitted
Implement core Virtual FileSystem functionality
Co-authored-by: KSemenenko <[email protected]>
1 parent 93223f4 commit ab47a4d

15 files changed

+3594
-6
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using ManagedCode.Storage.VirtualFileSystem.Core;
6+
7+
namespace ManagedCode.Storage.VirtualFileSystem.Core;
8+
9+
/// <summary>
10+
/// Base interface for virtual file system entries
11+
/// </summary>
12+
public interface IVfsEntry
13+
{
14+
/// <summary>
15+
/// Gets the path of this entry
16+
/// </summary>
17+
VfsPath Path { get; }
18+
19+
/// <summary>
20+
/// Gets the name of this entry
21+
/// </summary>
22+
string Name { get; }
23+
24+
/// <summary>
25+
/// Gets the type of this entry
26+
/// </summary>
27+
VfsEntryType Type { get; }
28+
29+
/// <summary>
30+
/// Gets when this entry was created
31+
/// </summary>
32+
DateTimeOffset CreatedOn { get; }
33+
34+
/// <summary>
35+
/// Gets when this entry was last modified
36+
/// </summary>
37+
DateTimeOffset LastModified { get; }
38+
39+
/// <summary>
40+
/// Checks if this entry exists
41+
/// </summary>
42+
/// <param name="cancellationToken">Cancellation token</param>
43+
/// <returns>True if the entry exists</returns>
44+
ValueTask<bool> ExistsAsync(CancellationToken cancellationToken = default);
45+
46+
/// <summary>
47+
/// Refreshes the entry information from storage
48+
/// </summary>
49+
/// <param name="cancellationToken">Cancellation token</param>
50+
/// <returns>Task representing the async operation</returns>
51+
Task RefreshAsync(CancellationToken cancellationToken = default);
52+
53+
/// <summary>
54+
/// Gets the parent directory of this entry
55+
/// </summary>
56+
/// <param name="cancellationToken">Cancellation token</param>
57+
/// <returns>The parent directory</returns>
58+
ValueTask<IVirtualDirectory> GetParentAsync(CancellationToken cancellationToken = default);
59+
}
60+
61+
/// <summary>
62+
/// Type of virtual file system entry
63+
/// </summary>
64+
public enum VfsEntryType
65+
{
66+
/// <summary>
67+
/// A file entry
68+
/// </summary>
69+
File,
70+
71+
/// <summary>
72+
/// A directory entry
73+
/// </summary>
74+
Directory
75+
}
76+
77+
/// <summary>
78+
/// Progress information for copy operations
79+
/// </summary>
80+
public class CopyProgress
81+
{
82+
/// <summary>
83+
/// Total number of bytes to copy
84+
/// </summary>
85+
public long TotalBytes { get; set; }
86+
87+
/// <summary>
88+
/// Number of bytes copied so far
89+
/// </summary>
90+
public long CopiedBytes { get; set; }
91+
92+
/// <summary>
93+
/// Total number of files to copy
94+
/// </summary>
95+
public int TotalFiles { get; set; }
96+
97+
/// <summary>
98+
/// Number of files copied so far
99+
/// </summary>
100+
public int CopiedFiles { get; set; }
101+
102+
/// <summary>
103+
/// Current file being copied
104+
/// </summary>
105+
public string? CurrentFile { get; set; }
106+
107+
/// <summary>
108+
/// Percentage completed (0-100)
109+
/// </summary>
110+
public double PercentageComplete => TotalBytes > 0 ? (double)CopiedBytes / TotalBytes * 100 : 0;
111+
}
112+
113+
/// <summary>
114+
/// Result of a delete directory operation
115+
/// </summary>
116+
public class DeleteDirectoryResult
117+
{
118+
/// <summary>
119+
/// Whether the operation was successful
120+
/// </summary>
121+
public bool Success { get; set; }
122+
123+
/// <summary>
124+
/// Number of files deleted
125+
/// </summary>
126+
public int FilesDeleted { get; set; }
127+
128+
/// <summary>
129+
/// Number of directories deleted
130+
/// </summary>
131+
public int DirectoriesDeleted { get; set; }
132+
133+
/// <summary>
134+
/// List of errors encountered during deletion
135+
/// </summary>
136+
public List<string> Errors { get; set; } = new();
137+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using ManagedCode.Storage.VirtualFileSystem.Options;
6+
7+
namespace ManagedCode.Storage.VirtualFileSystem.Core;
8+
9+
/// <summary>
10+
/// Represents a directory in the virtual filesystem
11+
/// </summary>
12+
public interface IVirtualDirectory : IVfsEntry
13+
{
14+
/// <summary>
15+
/// Lists files in this directory with pagination and pattern matching
16+
/// </summary>
17+
/// <param name="pattern">Search pattern for filtering</param>
18+
/// <param name="recursive">Whether to search recursively</param>
19+
/// <param name="pageSize">Page size for pagination</param>
20+
/// <param name="cancellationToken">Cancellation token</param>
21+
/// <returns>Async enumerable of files</returns>
22+
IAsyncEnumerable<IVirtualFile> GetFilesAsync(
23+
SearchPattern? pattern = null,
24+
bool recursive = false,
25+
int pageSize = 100,
26+
CancellationToken cancellationToken = default);
27+
28+
/// <summary>
29+
/// Lists subdirectories with pagination
30+
/// </summary>
31+
/// <param name="pattern">Search pattern for filtering</param>
32+
/// <param name="recursive">Whether to search recursively</param>
33+
/// <param name="pageSize">Page size for pagination</param>
34+
/// <param name="cancellationToken">Cancellation token</param>
35+
/// <returns>Async enumerable of directories</returns>
36+
IAsyncEnumerable<IVirtualDirectory> GetDirectoriesAsync(
37+
SearchPattern? pattern = null,
38+
bool recursive = false,
39+
int pageSize = 100,
40+
CancellationToken cancellationToken = default);
41+
42+
/// <summary>
43+
/// Lists all entries (files and directories) in this directory
44+
/// </summary>
45+
/// <param name="pattern">Search pattern for filtering</param>
46+
/// <param name="recursive">Whether to search recursively</param>
47+
/// <param name="pageSize">Page size for pagination</param>
48+
/// <param name="cancellationToken">Cancellation token</param>
49+
/// <returns>Async enumerable of entries</returns>
50+
IAsyncEnumerable<IVfsEntry> GetEntriesAsync(
51+
SearchPattern? pattern = null,
52+
bool recursive = false,
53+
int pageSize = 100,
54+
CancellationToken cancellationToken = default);
55+
56+
/// <summary>
57+
/// Creates a file in this directory
58+
/// </summary>
59+
/// <param name="name">File name</param>
60+
/// <param name="options">File creation options</param>
61+
/// <param name="cancellationToken">Cancellation token</param>
62+
/// <returns>The created file</returns>
63+
ValueTask<IVirtualFile> CreateFileAsync(
64+
string name,
65+
CreateFileOptions? options = null,
66+
CancellationToken cancellationToken = default);
67+
68+
/// <summary>
69+
/// Creates a subdirectory
70+
/// </summary>
71+
/// <param name="name">Directory name</param>
72+
/// <param name="cancellationToken">Cancellation token</param>
73+
/// <returns>The created directory</returns>
74+
ValueTask<IVirtualDirectory> CreateDirectoryAsync(
75+
string name,
76+
CancellationToken cancellationToken = default);
77+
78+
/// <summary>
79+
/// Gets statistics for this directory
80+
/// </summary>
81+
/// <param name="recursive">Whether to calculate recursively</param>
82+
/// <param name="cancellationToken">Cancellation token</param>
83+
/// <returns>Directory statistics</returns>
84+
Task<DirectoryStats> GetStatsAsync(
85+
bool recursive = true,
86+
CancellationToken cancellationToken = default);
87+
88+
/// <summary>
89+
/// Deletes this directory
90+
/// </summary>
91+
/// <param name="recursive">Whether to delete recursively</param>
92+
/// <param name="cancellationToken">Cancellation token</param>
93+
/// <returns>Delete operation result</returns>
94+
Task<DeleteDirectoryResult> DeleteAsync(
95+
bool recursive = false,
96+
CancellationToken cancellationToken = default);
97+
}
98+
99+
/// <summary>
100+
/// Statistics for a directory
101+
/// </summary>
102+
public class DirectoryStats
103+
{
104+
/// <summary>
105+
/// Number of files in the directory
106+
/// </summary>
107+
public int FileCount { get; init; }
108+
109+
/// <summary>
110+
/// Number of subdirectories
111+
/// </summary>
112+
public int DirectoryCount { get; init; }
113+
114+
/// <summary>
115+
/// Total size of all files in bytes
116+
/// </summary>
117+
public long TotalSize { get; init; }
118+
119+
/// <summary>
120+
/// File count by extension
121+
/// </summary>
122+
public Dictionary<string, int> FilesByExtension { get; init; } = new();
123+
124+
/// <summary>
125+
/// The largest file in the directory
126+
/// </summary>
127+
public IVirtualFile? LargestFile { get; init; }
128+
129+
/// <summary>
130+
/// Oldest modification date
131+
/// </summary>
132+
public DateTimeOffset? OldestModified { get; init; }
133+
134+
/// <summary>
135+
/// Newest modification date
136+
/// </summary>
137+
public DateTimeOffset? NewestModified { get; init; }
138+
}

0 commit comments

Comments
 (0)