Skip to content

Commit

Permalink
chore: Throw error if unable to convert enum to string.
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn committed Nov 29, 2024
1 parent c877a5d commit bd584dd
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
20 changes: 13 additions & 7 deletions src/Docker.DotNet/JsonEnumMemberConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,39 @@

internal sealed class JsonEnumMemberConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum
{
private readonly IReadOnlyDictionary<string, string> _map = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static)
private readonly Dictionary<string, string> _enumFields = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static)
.Select(field => (Name: field.Name, Attribute: field.GetCustomAttribute<EnumMemberAttribute>()))
.Where(item => item.Attribute != null && item.Attribute.Value != null)
.ToDictionary(item => item.Name, item => item.Attribute.Value, StringComparer.OrdinalIgnoreCase);
.ToDictionary(item => item.Name, item => item.Attribute.Value);

public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var stringValue = reader.GetString();

var enumValue = _map.SingleOrDefault(item => item.Value.Equals(stringValue, StringComparison.OrdinalIgnoreCase));
var enumField = _enumFields.SingleOrDefault(item => item.Value.Equals(stringValue, StringComparison.Ordinal));

if (enumValue.Key == null)
if (enumField.Key == null)
{
throw new JsonException($"Unknown enum value '{stringValue}' for enum type '{typeof(TEnum).Name}'.");
}

if (!Enum.TryParse(enumValue.Key, out TEnum result))
if (!Enum.TryParse(enumField.Key, out TEnum enumValue))
{
throw new JsonException($"Unable to convert '{stringValue}' to a valid enum value of type '{typeof(TEnum).Name}'.");
}

return result;
return enumValue;
}

public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
{
var enumName = value.ToString();
writer.WriteStringValue(_map.TryGetValue(enumName, out var stringValue) ? stringValue : enumName);

if (!_enumFields.TryGetValue(enumName, out var stringValue))
{
throw new JsonException($"Unable to convert '{enumName}' to a valid enum value of type '{nameof(String)}'.");
}

writer.WriteStringValue(stringValue);
}
}
2 changes: 1 addition & 1 deletion src/Docker.DotNet/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ internal sealed class JsonSerializer

private JsonSerializer()
{
_options.Converters.Add(new JsonEnumMemberConverter<TaskState>());
_options.Converters.Add(new JsonEnumMemberConverter<RestartPolicyKind>());
_options.Converters.Add(new JsonEnumMemberConverter<TaskState>());
_options.Converters.Add(new JsonDateTimeConverter());
_options.Converters.Add(new JsonNullableDateTimeConverter());
_options.Converters.Add(new JsonBase64Converter());
Expand Down
2 changes: 1 addition & 1 deletion test/Docker.DotNet.Tests/JsonEnumMemberConverterTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Docker.DotNet.JsonSerializer8.Tests;
namespace Docker.DotNet.Tests;

using System.Text;
using Docker.DotNet.Models;
Expand Down

0 comments on commit bd584dd

Please sign in to comment.