UrlPath Pennington.Routing
A URL path value supporting composition and normalization.
Properties
Valuestring- Underlying path string.
Constructors
.ctor
#public readonly record struct UrlPath(string Value)
{
/// <summary>Implicitly converts a string to a <see cref="UrlPath"/>.</summary>
public static implicit operator UrlPath(string value) => new(value);
/// <summary>Joins two URL path segments, normalizing slashes.</summary>
public static UrlPath operator /(UrlPath left, UrlPath right)
{
var l = left.Value.TrimEnd('/');
var r = right.Value.TrimStart('/');
if (string.IsNullOrEmpty(l)) return new UrlPath("/" + r);
if (string.IsNullOrEmpty(r)) return new UrlPath(l.StartsWith('/') ? l : "/" + l);
return new UrlPath(l + "/" + r);
}
/// <summary>Returns a path guaranteed to start with a slash.</summary>
public UrlPath EnsureLeadingSlash()
=> Value.StartsWith('/') ? this : new UrlPath("/" + Value);
/// <summary>Returns a path guaranteed to end with a slash.</summary>
public UrlPath EnsureTrailingSlash()
=> Value.EndsWith('/') ? this : new UrlPath(Value + "/");
/// <summary>Removes a trailing slash (except from the root path).</summary>
public UrlPath RemoveTrailingSlash()
=> Value.Length > 1 && Value.EndsWith('/') ? new UrlPath(Value[..^1]) : this;
/// <summary>Removes a leading slash if present.</summary>
public UrlPath RemoveLeadingSlash()
=> Value.StartsWith('/') ? new UrlPath(Value[1..]) : this;
/// <summary>Compares two URL paths ignoring trailing slashes, index.html suffixes, and case.</summary>
public bool Matches(UrlPath other)
{
var a = Normalize(Value);
var b = Normalize(other.Value);
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
private static string Normalize(string path)
{
var s = path.TrimEnd('/');
if (s.EndsWith("/index.html", StringComparison.OrdinalIgnoreCase))
s = s[..^"/index.html".Length];
else if (s.EndsWith("/index.htm", StringComparison.OrdinalIgnoreCase))
s = s[..^"/index.htm".Length];
if (string.IsNullOrEmpty(s)) s = "/";
return s.ToLowerInvariant();
}
/// <summary>Returns the underlying URL string.</summary>
public override string ToString() => Value;
}A URL path value supporting composition and normalization.
Parameters
Valuestring- Underlying path string.
Methods
EnsureLeadingSlash
#public UrlPath EnsureLeadingSlash();Returns a path guaranteed to start with a slash.
Returns
UrlPathEnsureTrailingSlash
#public UrlPath EnsureTrailingSlash();Returns a path guaranteed to end with a slash.
Returns
UrlPathMatches
#public bool Matches(UrlPath other);Compares two URL paths ignoring trailing slashes, index.html suffixes, and case.
Parameters
otherUrlPath
Returns
boolop_Division
#public static UrlPath operator /(UrlPath left, UrlPath right);Joins two URL path segments, normalizing slashes.
Parameters
leftUrlPathrightUrlPath
Returns
UrlPathop_Implicit
#public static implicit operator UrlPath(string value);Implicitly converts a string to a UrlPath.
Parameters
valuestring
Returns
UrlPathRemoveLeadingSlash
#public UrlPath RemoveLeadingSlash();Removes a leading slash if present.
Returns
UrlPathRemoveTrailingSlash
#public UrlPath RemoveTrailingSlash();Removes a trailing slash (except from the root path).
Returns
UrlPathToString
#public override string ToString();Returns the underlying URL string.
Returns
stringPennington.Routing.UrlPath
namespace Pennington.Routing;
/// A URL path value supporting composition and normalization.
public record UrlPath
{
/// A URL path value supporting composition and normalization.
public readonly record struct UrlPath(string Value)
{
/// <summary>Implicitly converts a string to a <see cref="UrlPath"/>.</summary>
public static implicit operator UrlPath(string value) => new(value);
/// <summary>Joins two URL path segments, normalizing slashes.</summary>
public static UrlPath operator /(UrlPath left, UrlPath right)
{
var l = left.Value.TrimEnd('/');
var r = right.Value.TrimStart('/');
if (string.IsNullOrEmpty(l)) return new UrlPath("/" + r);
if (string.IsNullOrEmpty(r)) return new UrlPath(l.StartsWith('/') ? l : "/" + l);
return new UrlPath(l + "/" + r);
}
/// <summary>Returns a path guaranteed to start with a slash.</summary>
public UrlPath EnsureLeadingSlash()
=> Value.StartsWith('/') ? this : new UrlPath("/" + Value);
/// <summary>Returns a path guaranteed to end with a slash.</summary>
public UrlPath EnsureTrailingSlash()
=> Value.EndsWith('/') ? this : new UrlPath(Value + "/");
/// <summary>Removes a trailing slash (except from the root path).</summary>
public UrlPath RemoveTrailingSlash()
=> Value.Length > 1 && Value.EndsWith('/') ? new UrlPath(Value[..^1]) : this;
/// <summary>Removes a leading slash if present.</summary>
public UrlPath RemoveLeadingSlash()
=> Value.StartsWith('/') ? new UrlPath(Value[1..]) : this;
/// <summary>Compares two URL paths ignoring trailing slashes, index.html suffixes, and case.</summary>
public bool Matches(UrlPath other)
{
var a = Normalize(Value);
var b = Normalize(other.Value);
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
private static string Normalize(string path)
{
var s = path.TrimEnd('/');
if (s.EndsWith("/index.html", StringComparison.OrdinalIgnoreCase))
s = s[..^"/index.html".Length];
else if (s.EndsWith("/index.htm", StringComparison.OrdinalIgnoreCase))
s = s[..^"/index.htm".Length];
if (string.IsNullOrEmpty(s)) s = "/";
return s.ToLowerInvariant();
}
/// <summary>Returns the underlying URL string.</summary>
public override string ToString() => Value;
}
/// Returns a path guaranteed to start with a slash.
public UrlPath EnsureLeadingSlash();
/// Returns a path guaranteed to end with a slash.
public UrlPath EnsureTrailingSlash();
/// Compares two URL paths ignoring trailing slashes, index.html suffixes, and case.
public bool Matches(UrlPath other);
/// Joins two URL path segments, normalizing slashes.
public static UrlPath operator /(UrlPath left, UrlPath right);
/// Implicitly converts a string to a UrlPath.
public static implicit operator UrlPath(string value);
/// Removes a leading slash if present.
public UrlPath RemoveLeadingSlash();
/// Removes a trailing slash (except from the root path).
public UrlPath RemoveTrailingSlash();
/// Returns the underlying URL string.
public override string ToString();
/// Underlying path string.
string Value
;
}