From d82eebcd7a37bf428bf23f5a8bba3bca30d67cdd Mon Sep 17 00:00:00 2001 From: Patrik Svensson Date: Tue, 9 Jul 2024 14:33:54 +0200 Subject: [PATCH] Implement IEquatable<> and IComparable<> for paths --- src/Spectre.IO/DirectoryPath.cs | 27 +++++++++++++++++++++- src/Spectre.IO/FilePath.cs | 27 +++++++++++++++++++++- src/Spectre.IO/Path.cs | 41 ++++++++++++++++++++++++++++++++- src/Spectre.IO/PathComparer.cs | 12 +++++++++- 4 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/Spectre.IO/DirectoryPath.cs b/src/Spectre.IO/DirectoryPath.cs index dc76f44..5f92f14 100644 --- a/src/Spectre.IO/DirectoryPath.cs +++ b/src/Spectre.IO/DirectoryPath.cs @@ -8,7 +8,7 @@ namespace Spectre.IO; /// /// Represents a directory path. /// -public sealed class DirectoryPath : Path +public sealed class DirectoryPath : Path, IEquatable, IComparable { /// /// Gets a value indicating whether or not the current @@ -240,4 +240,29 @@ public FilePath GetRelativePath(FilePath to) return GetRelativePath(to.GetDirectory()).GetFilePath(to.GetFilename()); } + + /// + public int CompareTo(DirectoryPath? other) + { + return PathComparer.Default.Compare(this, other); + } + + /// + public bool Equals(DirectoryPath? other) + { + return PathComparer.Default.Equals(this, other); + } + + /// + public override bool Equals(object? obj) + { + return ReferenceEquals(this, obj) + || (obj is DirectoryPath other && Equals(other)); + } + + /// + public override int GetHashCode() + { + return PathComparer.Default.GetHashCode(this); + } } \ No newline at end of file diff --git a/src/Spectre.IO/FilePath.cs b/src/Spectre.IO/FilePath.cs index a70abd9..d613236 100644 --- a/src/Spectre.IO/FilePath.cs +++ b/src/Spectre.IO/FilePath.cs @@ -6,7 +6,7 @@ namespace Spectre.IO; /// /// Represents a file path. /// -public sealed class FilePath : Path +public sealed class FilePath : Path, IEquatable, IComparable { /// /// Gets a value indicating whether this path has a file extension. @@ -240,4 +240,29 @@ public FilePath GetRelativePath(FilePath to) { return GetDirectory().GetRelativePath(to); } + + /// + public int CompareTo(FilePath? other) + { + return PathComparer.Default.Compare(this, other); + } + + /// + public bool Equals(FilePath? other) + { + return PathComparer.Default.Equals(this, other); + } + + /// + public override bool Equals(object? obj) + { + return ReferenceEquals(this, obj) + || (obj is FilePath other && Equals(other)); + } + + /// + public override int GetHashCode() + { + return PathComparer.Default.GetHashCode(this); + } } \ No newline at end of file diff --git a/src/Spectre.IO/Path.cs b/src/Spectre.IO/Path.cs index d86bc23..463332e 100644 --- a/src/Spectre.IO/Path.cs +++ b/src/Spectre.IO/Path.cs @@ -8,7 +8,7 @@ namespace Spectre.IO; /// Provides properties and instance methods for working with paths. /// This class must be inherited. /// -public abstract class Path +public abstract class Path : IEquatable, IComparable { private readonly string[] _segments; @@ -135,4 +135,43 @@ public override string ToString() { return FullPath; } + + /// + public int CompareTo(Path? other) + { + return PathComparer.Default.Compare(this, other); + } + + /// + public bool Equals(Path? other) + { + return PathComparer.Default.Equals(this, other); + } + + /// + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != this.GetType()) + { + return false; + } + + return Equals((Path)obj); + } + + /// + public override int GetHashCode() + { + return PathComparer.Default.GetHashCode(this); + } } \ No newline at end of file diff --git a/src/Spectre.IO/PathComparer.cs b/src/Spectre.IO/PathComparer.cs index 6396863..c61a625 100644 --- a/src/Spectre.IO/PathComparer.cs +++ b/src/Spectre.IO/PathComparer.cs @@ -55,7 +55,7 @@ public int Compare(Path? x, Path? y) } // This might look strange, - // but for some reason, null reference tracking + // but for some reason, nullable reference tracking // does not work correctly otherwise. if (x == null || y == null) { @@ -67,6 +67,11 @@ public int Compare(Path? x, Path? y) return 1; } + if (x.GetType() != y.GetType()) + { + return -1; + } + if (x.Segments.Count != y.Segments.Count) { return x.Segments.Count @@ -102,6 +107,11 @@ public bool Equals(Path? x, Path? y) return false; } + if (x.GetType() != y.GetType()) + { + return false; + } + if (x.Segments.Count != y.Segments.Count) { return false;