127 lines
4.5 KiB
C#
127 lines
4.5 KiB
C#
using System.Text.Json.Serialization;
|
|
|
|
namespace FinalFactory.Rendezvous.Contracts;
|
|
|
|
[JsonConverter(typeof(GameIdJsonConverter))]
|
|
public readonly struct GameId : IEquatable<GameId>
|
|
{
|
|
public GameId(string value)
|
|
{
|
|
if (!ContractValidation.IsSlug(value, ContractLimits.GameIdMaxCharacters))
|
|
{
|
|
throw new ArgumentException("Game IDs must be lowercase URL-safe slugs.", nameof(value));
|
|
}
|
|
|
|
Value = value;
|
|
}
|
|
|
|
public string Value { get; }
|
|
|
|
public static bool TryParse(string? value, out GameId gameId)
|
|
{
|
|
if (ContractValidation.IsSlug(value, ContractLimits.GameIdMaxCharacters))
|
|
{
|
|
gameId = new GameId(value!);
|
|
return true;
|
|
}
|
|
|
|
gameId = default;
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(GameId other) => string.Equals(Value, other.Value, StringComparison.Ordinal);
|
|
public override bool Equals(object? obj) => obj is GameId other && Equals(other);
|
|
public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(Value ?? string.Empty);
|
|
public override string ToString() => Value ?? string.Empty;
|
|
public static bool operator ==(GameId left, GameId right) => left.Equals(right);
|
|
public static bool operator !=(GameId left, GameId right) => !left.Equals(right);
|
|
}
|
|
|
|
[JsonConverter(typeof(EnvironmentIdJsonConverter))]
|
|
public readonly struct EnvironmentId : IEquatable<EnvironmentId>
|
|
{
|
|
public EnvironmentId(string value)
|
|
{
|
|
if (!ContractValidation.IsSlug(value, ContractLimits.EnvironmentIdMaxCharacters))
|
|
{
|
|
throw new ArgumentException("Environment IDs must be lowercase URL-safe slugs.", nameof(value));
|
|
}
|
|
|
|
Value = value;
|
|
}
|
|
|
|
public string Value { get; }
|
|
|
|
public static bool TryParse(string? value, out EnvironmentId environmentId)
|
|
{
|
|
if (ContractValidation.IsSlug(value, ContractLimits.EnvironmentIdMaxCharacters))
|
|
{
|
|
environmentId = new EnvironmentId(value!);
|
|
return true;
|
|
}
|
|
|
|
environmentId = default;
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(EnvironmentId other) => string.Equals(Value, other.Value, StringComparison.Ordinal);
|
|
public override bool Equals(object? obj) => obj is EnvironmentId other && Equals(other);
|
|
public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(Value ?? string.Empty);
|
|
public override string ToString() => Value ?? string.Empty;
|
|
public static bool operator ==(EnvironmentId left, EnvironmentId right) => left.Equals(right);
|
|
public static bool operator !=(EnvironmentId left, EnvironmentId right) => !left.Equals(right);
|
|
}
|
|
|
|
[JsonConverter(typeof(RegionIdJsonConverter))]
|
|
public readonly struct RegionId : IEquatable<RegionId>
|
|
{
|
|
public RegionId(string value)
|
|
{
|
|
if (!ContractValidation.IsSlug(value, ContractLimits.RegionIdMaxCharacters))
|
|
{
|
|
throw new ArgumentException("Region IDs must be lowercase URL-safe slugs.", nameof(value));
|
|
}
|
|
|
|
Value = value;
|
|
}
|
|
|
|
public string Value { get; }
|
|
|
|
public static bool TryParse(string? value, out RegionId regionId)
|
|
{
|
|
if (ContractValidation.IsSlug(value, ContractLimits.RegionIdMaxCharacters))
|
|
{
|
|
regionId = new RegionId(value!);
|
|
return true;
|
|
}
|
|
|
|
regionId = default;
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(RegionId other) => string.Equals(Value, other.Value, StringComparison.Ordinal);
|
|
public override bool Equals(object? obj) => obj is RegionId other && Equals(other);
|
|
public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(Value ?? string.Empty);
|
|
public override string ToString() => Value ?? string.Empty;
|
|
public static bool operator ==(RegionId left, RegionId right) => left.Equals(right);
|
|
public static bool operator !=(RegionId left, RegionId right) => !left.Equals(right);
|
|
}
|
|
|
|
internal sealed class GameIdJsonConverter : StringIdentifierJsonConverter<GameId>
|
|
{
|
|
protected override GameId Parse(string value) => new(value);
|
|
protected override string Format(GameId value) => value.Value;
|
|
}
|
|
|
|
internal sealed class EnvironmentIdJsonConverter : StringIdentifierJsonConverter<EnvironmentId>
|
|
{
|
|
protected override EnvironmentId Parse(string value) => new(value);
|
|
protected override string Format(EnvironmentId value) => value.Value;
|
|
}
|
|
|
|
internal sealed class RegionIdJsonConverter : StringIdentifierJsonConverter<RegionId>
|
|
{
|
|
protected override RegionId Parse(string value) => new(value);
|
|
protected override string Format(RegionId value) => value.Value;
|
|
}
|