// 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);
}
}
}