You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.3 KiB
124 lines
3.3 KiB
using System.ComponentModel; |
|
using System.Diagnostics.CodeAnalysis; |
|
using JetBrains.Annotations; |
|
|
|
namespace StabilityMatrix.Core.Models.FileInterfaces; |
|
|
|
[PublicAPI] |
|
[Localizable(false)] |
|
public class FileSystemPath : IEquatable<FileSystemPath>, IFormattable |
|
{ |
|
public string FullPath { get; } |
|
|
|
protected FileSystemPath(string path) |
|
{ |
|
FullPath = path; |
|
} |
|
|
|
protected FileSystemPath(FileSystemPath path) |
|
: this(path.FullPath) { } |
|
|
|
protected FileSystemPath(params string[] paths) |
|
: this(Path.Combine(paths)) { } |
|
|
|
/// <inheritdoc /> |
|
public override string ToString() |
|
{ |
|
return FullPath; |
|
} |
|
|
|
/// <inheritdoc /> |
|
string IFormattable.ToString(string? format, IFormatProvider? formatProvider) |
|
{ |
|
return ToString(format, formatProvider); |
|
} |
|
|
|
/// <summary> |
|
/// Overridable IFormattable.ToString method. |
|
/// By default, returns <see cref="FullPath"/>. |
|
/// </summary> |
|
protected virtual string ToString(string? format, IFormatProvider? formatProvider) |
|
{ |
|
return FullPath; |
|
} |
|
|
|
public static bool operator ==(FileSystemPath? left, FileSystemPath? right) |
|
{ |
|
return Equals(left, right); |
|
} |
|
|
|
public static bool operator !=(FileSystemPath? left, FileSystemPath? right) |
|
{ |
|
return !Equals(left, right); |
|
} |
|
|
|
/// <inheritdoc /> |
|
public bool Equals(FileSystemPath? other) |
|
{ |
|
if (ReferenceEquals(null, other)) |
|
return false; |
|
if (ReferenceEquals(this, other)) |
|
return true; |
|
|
|
return string.Equals( |
|
GetNormalizedPath(FullPath), |
|
GetNormalizedPath(other.FullPath), |
|
OperatingSystem.IsWindows() ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal |
|
); |
|
} |
|
|
|
/// <inheritdoc /> |
|
public override bool Equals(object? obj) |
|
{ |
|
if (ReferenceEquals(null, obj)) |
|
return false; |
|
if (ReferenceEquals(this, obj)) |
|
return true; |
|
if (GetType() != obj.GetType()) |
|
return false; |
|
return Equals((FileSystemPath)obj); |
|
} |
|
|
|
/// <summary> |
|
/// Normalize a path to a consistent format for comparison. |
|
/// </summary> |
|
/// <param name="path">Path to normalize.</param> |
|
/// <returns>Normalized path.</returns> |
|
[return: NotNullIfNotNull(nameof(path))] |
|
private static string? GetNormalizedPath(string? path) |
|
{ |
|
// Return null or empty paths as-is |
|
if (string.IsNullOrEmpty(path)) |
|
{ |
|
return path; |
|
} |
|
|
|
if (Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out var uri)) |
|
{ |
|
if (uri.IsAbsoluteUri) |
|
{ |
|
path = uri.LocalPath; |
|
} |
|
} |
|
|
|
// Get full path if possible, ignore errors like invalid chars or too long |
|
try |
|
{ |
|
path = Path.GetFullPath(path); |
|
} |
|
catch (SystemException) { } |
|
|
|
return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); |
|
} |
|
|
|
/// <inheritdoc /> |
|
public override int GetHashCode() |
|
{ |
|
return HashCode.Combine(GetType().GetHashCode(), FullPath.GetHashCode()); |
|
} |
|
|
|
// Implicit conversions to and from string |
|
public static implicit operator string(FileSystemPath path) => path.FullPath; |
|
|
|
public static implicit operator FileSystemPath(string path) => new(path); |
|
}
|
|
|