// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; namespace EpicGames.Horde.Acls { /// /// Name of an ACL scope /// [DebuggerDisplay("{Text}")] [JsonConverter(typeof(AclScopeNameJsonConverter))] [TypeConverter(typeof(AclScopeNameTypeConverter))] public record struct AclScopeName(string Text) { /// /// The root scope name /// public static AclScopeName Root { get; } = new AclScopeName("horde"); /// /// Append another name to this scope /// /// Name to append /// New scope name public AclScopeName Append(string name) => String.IsNullOrEmpty(Text)? new AclScopeName(name) : new AclScopeName($"{Text}/{name}"); /// public bool Equals(AclScopeName other) => String.Equals(Text ?? String.Empty, other.Text ?? String.Empty, StringComparison.Ordinal); /// public override int GetHashCode() => (Text ?? String.Empty).GetHashCode(StringComparison.Ordinal); /// public override string ToString() => Text; } /// /// Serializes objects to JSON /// class AclScopeNameJsonConverter : JsonConverter { /// public override AclScopeName Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => new AclScopeName(reader.GetString() ?? String.Empty); /// public override void Write(Utf8JsonWriter writer, AclScopeName value, JsonSerializerOptions options) => writer.WriteStringValue(value.Text); } /// /// Converts objects to strings /// class AclScopeNameTypeConverter : TypeConverter { /// public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } /// public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string str) { return new AclScopeName(str); } return base.ConvertFrom(context, culture, value); } /// public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } /// public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (destinationType == typeof(string)) { return value?.ToString(); } return base.ConvertTo(context, culture, value, destinationType); } } }