Skip to content

Commit

Permalink
Added relative file support
Browse files Browse the repository at this point in the history
  • Loading branch information
EGSP committed Dec 14, 2022
1 parent 91f1c6d commit 2ad3b9e
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 23 deletions.
46 changes: 46 additions & 0 deletions Automata/IO/DirectoryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,52 @@ public static async Task<List<IFile>> Files(this IDirectory dir)
return direcotryInfo.GetFiles().Select(x => new File(dir, x.Name)).ToList<IFile>();
}

public static async IAsyncEnumerable<IFile> EnumerateFiles(this IDirectory dir)
{
var directoryInfo = new DirectoryInfo(dir.Path);
foreach (var enumerateFile in directoryInfo.EnumerateFiles())
{
yield return dir.File(enumerateFile.Name);
}
}

public static async Task<List<IFile>> FilesDeep(this IDirectory root)
{
var files = new List<IFile>();
foreach (var dir in await root.Directories())
{
files.AddRange(await FilesDeep(dir));
}

var rootFiles = await root.Files();
files.AddRange(rootFiles);
return files;
}

public static async Task<List<IFile>> FilesDeep(this IDirectory root, Predicate<IFile> predicate)
{
var files = new List<IFile>();
foreach (var dir in await root.Directories())
{
files.AddRange(await FilesDeep(dir, predicate));
}

var rootFiles = await root.Files();
files.AddRange(rootFiles.Where(x => predicate(x)));
return files;
}

public static async IAsyncEnumerable<IFile> EnumerateFilesDeep(this IDirectory root)
{
await foreach (var enumerateFile in root.EnumerateFiles())
yield return enumerateFile;

// Проходим по всем подпапкам
foreach (var directory in await root.Directories())
await foreach (var file in directory.EnumerateFilesDeep())
yield return file;
}

public static async Task<List<IDirectory>> Directories(this IDirectory dir)
{
var dirInfo = new DirectoryInfo(dir.Path);
Expand Down
8 changes: 4 additions & 4 deletions Automata/IO/IDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ namespace Automata.IO;

public interface IDirectory : IO
{
IDirectory? Root { get; }
}

public sealed class Directory : IDirectory
{
public string Path { get; }
public IDirectory? Root { get; }

public Directory(string path)
{
Path = IOShared.FileSystem.Path.GetFullPath(path + "/");
Path = IO.CorrectSlash(path + "/");
}

public Directory(IDirectory root, string name)
{
Root = root;
Path = IOShared.FileSystem.Path.GetFullPath(Root.Path + "/" + name);
Path = IO.CorrectSlash(Root.Path + "/" + name);
}

public string Path { get; }
}
4 changes: 2 additions & 2 deletions Automata/IO/IFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ public interface IFile : IO

public sealed class File : IFile
{
public string Path { get; }
public IDirectory Directory { get; }
public string Name { get; }

public File(IDirectory directory, string name)
{
Path = IO.CorrectSlash(Directory.Path + "/" + Name);
Directory = directory;
Name = name;
}

public string Path => IOShared.FileSystem.Path.GetFullPath(Directory.Path + "/" + Name);
}
67 changes: 50 additions & 17 deletions Automata/IO/IO.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,63 @@
using System.IO.Abstractions;
using System.Text;

namespace Automata.IO;

public interface IO
{
public string Path { get; }
}

public static class IOShared
{
static IOShared()
{
FileSystem = null;
}
string Path { get; }

private static IFileSystem _fileSystem = null!;
public static IFileSystem FileSystem
static string CorrectSlash(string path)
{
get => _fileSystem;
set
var builder = new StringBuilder(path.Length);
for (var i = 0; i < path.Length; i++)
{
if (value == null)
var c = path[i];
switch (c)
{
value = new FileSystem();
case '/':
Slash(ref i, path, builder); break;
case '\\':
Slash(ref i, path, builder); break;
default: builder.Append(c);
break;
}
_fileSystem = value;
}
void Slash(ref int index, string source, StringBuilder builder)
{
builder.Append('/');
index++;
for (;index < source.Length; index++)
{
var c = source[index];
if (c == '/' || c == '\\')
continue;
index--;
return;
}
}
return builder.ToString();
}
}

// ReSharper disable once InconsistentNaming
public interface RelativeIO : IO
{
public static string SubtractLeft(string leftPath, string fullPath)
=> IO.CorrectSlash(fullPath).Substring(IO.CorrectSlash(leftPath).Length);

public static IRelativeDirectory RelativeDirectory(
string leftPath, string fullPath)
{
return new RelativeDirectory(SubtractLeft(leftPath, fullPath));
}

public static IRelativeFile RelativeFile(string leftPath, string fullPath)
{
var relativePath = SubtractLeft(leftPath, fullPath);
var directoryPath = IOShared.FileSystem.Path.GetDirectoryName(relativePath);
var filename = IOShared.FileSystem.Path.GetFileName(relativePath);

return new RelativeFile(new RelativeDirectory(directoryPath), filename);
}
}

25 changes: 25 additions & 0 deletions Automata/IO/IOShared.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO.Abstractions;

namespace Automata.IO;
// ReSharper disable once InconsistentNaming
public static class IOShared
{
static IOShared()
{
FileSystem = null;
}

private static IFileSystem _fileSystem = null!;
public static IFileSystem FileSystem
{
get => _fileSystem;
set
{
if (value == null)
{
value = new FileSystem();
}
_fileSystem = value;
}
}
}
21 changes: 21 additions & 0 deletions Automata/IO/Relatives/IRelativeDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Automata.IO;

public interface IRelativeDirectory : IO
{

}

public class RelativeDirectory : IRelativeDirectory
{
public string Path { get; }

public RelativeDirectory(string path)
{
Path = IO.CorrectSlash(path);
}

public RelativeDirectory(IRelativeDirectory root, string name)
{
Path = IO.CorrectSlash(root.Path + "/" + name);
}
}
22 changes: 22 additions & 0 deletions Automata/IO/Relatives/IRelativeFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Automata.IO;

public interface IRelativeFile : IO
{
IRelativeDirectory RelativeRoot { get; }
string Name { get; }
}

public class RelativeFile : IRelativeFile
{
public string Path { get; }

public IRelativeDirectory RelativeRoot { get; }
public string Name { get; }

public RelativeFile(IRelativeDirectory root, string name)
{
RelativeRoot = root;
Name = name;
Path = IO.CorrectSlash(RelativeRoot.Path + name);
}
}
10 changes: 10 additions & 0 deletions Automata/IO/Relatives/RelativeDirectoryExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Automata.IO;

public static class RelativeDirectoryExtensions
{
public static IRelativeDirectory Directory(this IRelativeDirectory root, string name)
=> new RelativeDirectory(root, name);

public static IRelativeFile File(this IRelativeDirectory dir, string file)
=> new RelativeFile(dir, file);
}
9 changes: 9 additions & 0 deletions Automata/IO/Relatives/RelativeFileExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Automata.IO;

public static class RelativeFileExtensions
{
public static IRelativeFile RelativeFile(this IFile file, IDirectory excludeDirectoryPath)
{
return RelativeIO.RelativeFile(excludeDirectoryPath.Path, file.Path);
}
}

0 comments on commit 2ad3b9e

Please sign in to comment.