diff --git a/src/Docker.DotNet/JsonEnumMemberConverter.cs b/src/Docker.DotNet/JsonEnumMemberConverter.cs new file mode 100644 index 00000000..dbb60799 --- /dev/null +++ b/src/Docker.DotNet/JsonEnumMemberConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Docker.DotNet; + +// Adapted from https://github.com/dotnet/runtime/issues/74385#issuecomment-1705083109 +internal sealed class JsonEnumMemberConverter : JsonStringEnumConverter where TEnum : struct, Enum +{ + public JsonEnumMemberConverter() : base(namingPolicy: ResolveNamingPolicy()) + { + } + + private static JsonNamingPolicy ResolveNamingPolicy() + { + var map = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static) + .Select(f => (f.Name, AttributeName: f.GetCustomAttribute()?.Value)) + .Where(pair => pair.AttributeName != null) + .ToDictionary(e => e.Name, e => e.AttributeName); + + return map.Count > 0 ? new EnumMemberNamingPolicy(map) : null; + } + + private sealed class EnumMemberNamingPolicy : JsonNamingPolicy + { + private readonly IReadOnlyDictionary _map; + + public EnumMemberNamingPolicy(IReadOnlyDictionary map) => _map = map; + + public override string ConvertName(string name) => _map.TryGetValue(name, out var newName) ? newName : name; + } +} \ No newline at end of file diff --git a/src/Docker.DotNet/JsonSerializer.cs b/src/Docker.DotNet/JsonSerializer.cs index d3395e1c..f3897f83 100644 --- a/src/Docker.DotNet/JsonSerializer.cs +++ b/src/Docker.DotNet/JsonSerializer.cs @@ -9,6 +9,7 @@ using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; +using Docker.DotNet.Models; namespace Docker.DotNet { @@ -21,9 +22,10 @@ internal class JsonSerializer { Converters = { + new JsonEnumMemberConverter(), + new JsonEnumMemberConverter(), new JsonDateTimeConverter(), new JsonNullableDateTimeConverter(), - new JsonStringEnumConverter(), new JsonBase64Converter(), }, };