diff --git a/src/Spectre.IO.Tests/Unit/PathComparerTests.cs b/src/Spectre.IO.Tests/Unit/PathComparerTests.cs
index 263823f..f7be9b5 100644
--- a/src/Spectre.IO.Tests/Unit/PathComparerTests.cs
+++ b/src/Spectre.IO.Tests/Unit/PathComparerTests.cs
@@ -15,10 +15,10 @@ public sealed class TheEqualsMethod
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Same_Asset_Instances_Is_Considered_Equal(bool isCaseSensitive)
+ public void Same_Asset_Instances_Is_Considered_Equal(bool caseSensitive)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var path = new FilePath("shaders/basic.vert");
// When
@@ -31,10 +31,10 @@ public void Same_Asset_Instances_Is_Considered_Equal(bool isCaseSensitive)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Two_Null_Paths_Are_Considered_Equal(bool isCaseSensitive)
+ public void Two_Null_Paths_Are_Considered_Equal(bool caseSensitive)
{
// Given
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
// When
var result = comparer.Equals(null, null);
@@ -46,10 +46,10 @@ public void Two_Null_Paths_Are_Considered_Equal(bool isCaseSensitive)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Paths_Are_Considered_Inequal_If_Any_Is_Null(bool isCaseSensitive)
+ public void Paths_Are_Considered_Inequal_If_Any_Is_Null(bool caseSensitive)
{
// Given
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
// When
var result = comparer.Equals(null, new FilePath("test.txt"));
@@ -61,10 +61,10 @@ public void Paths_Are_Considered_Inequal_If_Any_Is_Null(bool isCaseSensitive)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Same_Paths_Are_Considered_Equal(bool isCaseSensitive)
+ public void Same_Paths_Are_Considered_Equal(bool caseSensitive)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("shaders/basic.vert");
@@ -76,10 +76,10 @@ public void Same_Paths_Are_Considered_Equal(bool isCaseSensitive)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Different_Paths_Are_Not_Considered_Equal(bool isCaseSensitive)
+ public void Different_Paths_Are_Not_Considered_Equal(bool caseSensitive)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("shaders/basic.frag");
@@ -92,10 +92,10 @@ public void Different_Paths_Are_Not_Considered_Equal(bool isCaseSensitive)
[InlineData(true, false)]
[InlineData(false, true)]
public void Same_Paths_But_Different_Casing_Are_Considered_Equal_Depending_On_Case_Sensitivity(
- bool isCaseSensitive, bool expected)
+ bool caseSensitive, bool expected)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("SHADERS/BASIC.VERT");
@@ -120,7 +120,7 @@ public void Should_Sort_Paths()
// When
var result = paths
- .Order(new PathComparer(isCaseSensitive: false))
+ .Order(new PathComparer(caseSensitive: false))
.ToList();
// Then
@@ -149,10 +149,10 @@ public void Should_Throw_If_Other_Path_Is_Null()
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Same_Paths_Get_Same_Hash_Code(bool isCaseSensitive)
+ public void Same_Paths_Get_Same_Hash_Code(bool caseSensitive)
{
// Given
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("shaders/basic.vert");
@@ -167,10 +167,10 @@ public void Same_Paths_Get_Same_Hash_Code(bool isCaseSensitive)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Different_Paths_Get_Different_Hash_Codes(bool isCaseSensitive)
+ public void Different_Paths_Get_Different_Hash_Codes(bool caseSensitive)
{
// Given
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("shaders/basic.frag");
@@ -186,10 +186,10 @@ public void Different_Paths_Get_Different_Hash_Codes(bool isCaseSensitive)
[InlineData(true, false)]
[InlineData(false, true)]
public void Same_Paths_But_Different_Casing_Get_Same_Hash_Code_Depending_On_Case_Sensitivity(
- bool isCaseSensitive, bool expected)
+ bool caseSensitive, bool expected)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
var first = new FilePath("shaders/basic.vert");
var second = new FilePath("SHADERS/BASIC.VERT");
@@ -222,13 +222,13 @@ public sealed class TheIsCaseSensitiveProperty
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void Should_Return_Whether_Or_Not_The_Comparer_Is_Case_Sensitive(bool isCaseSensitive)
+ public void Should_Return_Whether_Or_Not_The_Comparer_Is_Case_Sensitive(bool caseSensitive)
{
// Given, When
- var comparer = new PathComparer(isCaseSensitive);
+ var comparer = new PathComparer(caseSensitive);
// Then
- comparer.IsCaseSensitive.ShouldBe(isCaseSensitive);
+ comparer.IsCaseSensitive.ShouldBe(caseSensitive);
}
}
}
\ No newline at end of file
diff --git a/src/Spectre.IO/PathComparer.cs b/src/Spectre.IO/PathComparer.cs
index f58aaaa..6396863 100644
--- a/src/Spectre.IO/PathComparer.cs
+++ b/src/Spectre.IO/PathComparer.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using Spectre.IO.Internal;
namespace Spectre.IO;
@@ -11,7 +12,8 @@ public sealed class PathComparer : IPathComparer
///
/// Gets the default path comparer.
///
- public static PathComparer Default { get; } = new PathComparer(EnvironmentHelper.IsUnix());
+ public static PathComparer Default { get; }
+ = new PathComparer(EnvironmentHelper.IsUnix());
///
/// Gets a value indicating whether comparison is case sensitive.
@@ -24,10 +26,10 @@ public sealed class PathComparer : IPathComparer
///
/// Initializes a new instance of the class.
///
- /// if set to true, comparison is case sensitive.
- public PathComparer(bool isCaseSensitive)
+ /// if set to true, comparison is case sensitive.
+ public PathComparer(bool caseSensitive)
{
- IsCaseSensitive = isCaseSensitive;
+ IsCaseSensitive = caseSensitive;
}
///
@@ -52,26 +54,39 @@ public int Compare(Path? x, Path? y)
return 0;
}
- if (x != null && y == null)
+ // This might look strange,
+ // but for some reason, null reference tracking
+ // does not work correctly otherwise.
+ if (x == null || y == null)
{
- return -1;
+ if (x != null && y == null)
+ {
+ return -1;
+ }
+
+ return 1;
}
- if (x == null && y != null)
+ if (x.Segments.Count != y.Segments.Count)
{
- return 1;
+ return x.Segments.Count
+ .CompareTo(y.Segments.Count);
}
- if (IsCaseSensitive)
+ var comparer = IsCaseSensitive
+ ? StringComparer.Ordinal
+ : StringComparer.OrdinalIgnoreCase;
+
+ foreach (var (segmentX, segmentY) in x.Segments.Zip(y.Segments))
{
- return StringComparer.Ordinal.Compare(
- x!.FullPath,
- y!.FullPath);
+ var sort = comparer.Compare(segmentX, segmentY);
+ if (sort != 0)
+ {
+ return sort;
+ }
}
- return StringComparer.OrdinalIgnoreCase.Compare(
- x!.FullPath,
- y!.FullPath);
+ return 0;
}
///
@@ -87,12 +102,24 @@ public bool Equals(Path? x, Path? y)
return false;
}
- if (IsCaseSensitive)
+ if (x.Segments.Count != y.Segments.Count)
+ {
+ return false;
+ }
+
+ var comparer = IsCaseSensitive
+ ? StringComparer.Ordinal
+ : StringComparer.OrdinalIgnoreCase;
+
+ foreach (var (segmentX, segmentY) in x.Segments.Zip(y.Segments))
{
- return x.FullPath.Equals(y.FullPath, StringComparison.Ordinal);
+ if (!comparer.Equals(segmentX, segmentY))
+ {
+ return false;
+ }
}
- return x.FullPath.Equals(y.FullPath, StringComparison.OrdinalIgnoreCase);
+ return true;
}
///