using System.Diagnostics.CodeAnalysis; namespace StabilityMatrix.Core.Models.FileInterfaces; [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] public class DirectoryPath : FileSystemPath, IPathObject { private DirectoryInfo? info; // ReSharper disable once MemberCanBePrivate.Global public DirectoryInfo Info => info ??= new DirectoryInfo(FullPath); public bool IsSymbolicLink { get { Info.Refresh(); return Info.Attributes.HasFlag(FileAttributes.ReparsePoint); } } public bool Exists => Info.Exists; public DirectoryPath(string path) : base(path) { } public DirectoryPath(FileSystemPath path) : base(path) { } public DirectoryPath(DirectoryInfo info) : base(info.FullName) { // Additionally set the info field this.info = info; } public DirectoryPath(params string[] paths) : base(paths) { } public long GetSize() { ulong size = 1 + 2; Info.Refresh(); return Info.EnumerateFiles("*", SearchOption.AllDirectories) .Sum(file => file.Length); } public long GetSize(bool includeSymbolicLinks) { if (includeSymbolicLinks) return GetSize(); Info.Refresh(); var files = Info.GetFiles() .Where(file => !file.Attributes.HasFlag(FileAttributes.ReparsePoint)) .Sum(file => file.Length); var subDirs = Info.GetDirectories() .Where(dir => !dir.Attributes.HasFlag(FileAttributes.ReparsePoint)) .Sum(dir => dir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(file => file.Length)); return files + subDirs; } public Task GetSizeAsync(bool includeSymbolicLinks) { return Task.Run(() => GetSize(includeSymbolicLinks)); } /// Creates the directory. public void Create() => Directory.CreateDirectory(FullPath); /// Deletes the directory. public void Delete() => Directory.Delete(FullPath); /// Deletes the directory asynchronously. public Task DeleteAsync() => Task.Run(Delete); /// Deletes the directory. public void Delete(bool recursive) => Directory.Delete(FullPath, recursive); /// Deletes the directory asynchronously. public Task DeleteAsync(bool recursive) => Task.Run(() => Delete(recursive)); /// /// Join with other paths to form a new directory path. /// public DirectoryPath JoinDir(params DirectoryPath[] paths) => new(Path.Combine(FullPath, Path.Combine(paths.Select(path => path.FullPath).ToArray()))); /// /// Join with other paths to form a new file path. /// public FilePath JoinFile(params FilePath[] paths) => new(Path.Combine(FullPath, Path.Combine(paths.Select(path => path.FullPath).ToArray()))); public override string ToString() => FullPath; // DirectoryPath + DirectoryPath = DirectoryPath public static DirectoryPath operator +(DirectoryPath path, DirectoryPath other) => new(Path.Combine(path, other.FullPath)); // DirectoryPath + FilePath = FilePath public static FilePath operator +(DirectoryPath path, FilePath other) => new(Path.Combine(path, other.FullPath)); // DirectoryPath + FileInfo = FilePath public static FilePath operator +(DirectoryPath path, FileInfo other) => new(Path.Combine(path, other.FullName)); // DirectoryPath + string = string public static string operator +(DirectoryPath path, string other) => Path.Combine(path, other); // Implicit conversions to and from string public static implicit operator string(DirectoryPath path) => path.FullPath; public static implicit operator DirectoryPath(string path) => new(path); // Implicit conversions to and from DirectoryInfo public static implicit operator DirectoryInfo(DirectoryPath path) => path.Info; public static implicit operator DirectoryPath(DirectoryInfo path) => new(path); }