PkmnLib.NET/PkmnLib.Static/Utils/StringKey.cs

62 lines
2.5 KiB
C#

namespace PkmnLib.Static.Utils;
/// <summary>
/// A case-insensitive string key. We use this class for things like looking up data from dictionaries, etc.
/// </summary>
/// <remarks>
/// This is a struct, as it's effectively just a wrapper around a single reference object. Heap allocation would be silly.
/// </remarks>
public readonly record struct StringKey
{
private readonly string _key;
/// <inheritdoc cref="StringKey"/>
public StringKey(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentException("Key cannot be null or whitespace.", nameof(key));
_key = key;
}
/// <summary>
/// Converts a <see cref="StringKey"/> to a <see cref="string"/>.
/// </summary>
public static implicit operator string(StringKey key) => key._key;
/// <summary>
/// Converts a <see cref="string"/> to a <see cref="StringKey"/>.
/// </summary>
public static implicit operator StringKey(string key) =>
string.IsNullOrWhiteSpace(key) ? default : new StringKey(key);
/// <inheritdoc cref="string.ToString()"/>
public override string ToString() => _key.ToLowerInvariant();
/// <inheritdoc />
public bool Equals(StringKey other) => string.Equals(_key, other._key, StringComparison.InvariantCultureIgnoreCase);
/// <inheritdoc cref="Equals(StringKey)"/>
public bool Equals(string other) => string.Equals(_key, other, StringComparison.InvariantCultureIgnoreCase);
/// <inheritdoc />
public override int GetHashCode() => StringComparer.InvariantCultureIgnoreCase.GetHashCode(_key);
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator ==(StringKey left, string right) => left.Equals(right);
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator !=(StringKey left, string right) => !(left == right);
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator ==(StringKey? left, string? right) =>
(left is null && right is null) || (right != null && (left?.Equals(right) ?? false));
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator !=(StringKey? left, string? right) => !(left == right);
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator ==(StringKey? left, StringKey right) => left?.Equals(right) ?? false;
/// <inheritdoc cref="Equals(StringKey)"/>
public static bool operator !=(StringKey? left, StringKey right) => !(left == right);
}