Skip to content

Commit

Permalink
Fixes in JsonEnumIntValueConverter and JsonEnumValueConverter for def…
Browse files Browse the repository at this point in the history
…ault enum values.
  • Loading branch information
o.nadymov committed Aug 2, 2024
1 parent e46f6a3 commit 099a765
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 25 deletions.
14 changes: 9 additions & 5 deletions src/Spoleto.Common.Tests/JsonHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void EnumWithJsonEnumValueAttribute()
// Arrange
var obj = new TestClass
{
Test = TestEnumValue.Two
Test1 = TestEnumValue.Two
};

// Act
Expand All @@ -40,7 +40,7 @@ public void EnumWithJsonEnumValueAttribute()
// Assert
Assert.Multiple(() =>
{
Assert.That(fromJson.Test, Is.EqualTo(obj.Test));
Assert.That(fromJson.Test1, Is.EqualTo(obj.Test1));
Assert.That(json.Contains("T2"), Is.True);
});
}
Expand All @@ -51,7 +51,8 @@ public void EnumWithNullJsonEnumValueAttribute()
// Arrange
var obj = new TestClass
{
Test = TestEnumValue.Null
Test1 = TestEnumValue.Null,
Test2 = TestEnumValue.Two
};

// Act
Expand All @@ -61,8 +62,11 @@ public void EnumWithNullJsonEnumValueAttribute()
// Assert
Assert.Multiple(() =>
{
Assert.That(fromJson.Test, Is.EqualTo(obj.Test));
Assert.That(json.Contains("null"), Is.True);
Assert.That(fromJson.Test1, Is.EqualTo(obj.Test1));
Assert.That(fromJson.Test2, Is.EqualTo(obj.Test2));
Assert.That(json, Does.Contain("null"));
Assert.That(json, Does.Contain("\"T2\""));
});
}

Expand Down
5 changes: 4 additions & 1 deletion src/Spoleto.Common.Tests/Objects/TestClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ namespace Spoleto.Common.Tests
public class TestClass
{
[JsonConverter(typeof(JsonEnumValueConverter<TestEnumValue>))]
public TestEnumValue Test { get; set; }
public TestEnumValue Test1 { get; set; }

[JsonConverter(typeof(JsonEnumValueConverter<TestEnumValue>))]
public TestEnumValue Test2 { get; set; }

[JsonConverter(typeof(JsonIntEnumConverter<TestIntEnum>))]
public TestIntEnum TestIntEnum { get; set; }
Expand Down
6 changes: 3 additions & 3 deletions src/Spoleto.Common.Tests/Objects/TestEnumValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ namespace Spoleto.Common.Tests
public enum TestEnumValue
{
[JsonEnumValue("O1")]
One,
One = 1,

[JsonEnumValue("T2")]
Two,
Two = 2,

[JsonEnumValue(null)]
Null
Null = -1
}
}
34 changes: 26 additions & 8 deletions src/Spoleto.Common/JsonConverters/JsonEnumIntValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,44 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial
}
}

throw new JsonException($"Unknown enum element: {value}");
if (value == 0)
{
return default;
}

throw new JsonException($"Unknown enum '{typeof(T).Name}' element: {value}");
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var enumValue = GetEnumValue(value);

if (enumValue == null)
writer.WriteNullValue();
if (TryGetEnumValue(value, out var enumValue))
{
if (enumValue == null)
writer.WriteNullValue();
else
writer.WriteNumberValue(enumValue.Value);
}
else
writer.WriteNumberValue(enumValue.Value);
{
writer.WriteNumberValue((int)(object)value);
}
}

private int? GetEnumValue(Enum value)
private bool TryGetEnumValue(Enum value, out int? outValue)
{
var field = value.GetType().GetField(value.ToString());

return field.GetCustomAttribute<JsonEnumIntValueAttribute>() is JsonEnumIntValueAttribute attribute
if (field == null)
{
outValue = null;
return false;
}

outValue = field.GetCustomAttribute<JsonEnumIntValueAttribute>() is JsonEnumIntValueAttribute attribute
? attribute.Value
: Convert.ToInt32(value);

return true;
}
}
}
37 changes: 29 additions & 8 deletions src/Spoleto.Common/JsonConverters/JsonEnumValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial
{
value = null;
}
else if (reader.TokenType == JsonTokenType.Number)
{
var numValue = reader.GetInt32();
if (numValue == 0)
return default;

throw new JsonException($"Unknown enum '{typeof(T).Name}' element: {numValue}");
}
else
{
value = reader.GetString();
Expand All @@ -40,26 +48,39 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial
}
}

throw new JsonException($"Unknown enum element: {value}");
throw new JsonException($"Unknown enum '{typeof(T).Name}' element: {value}");
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var enumValue = GetEnumValue(value);

if (enumValue == null)
writer.WriteNullValue();
if (TryGetEnumValue(value, out var enumValue))
{
if (enumValue == null)
writer.WriteNullValue();
else
writer.WriteStringValue(enumValue);
}
else
writer.WriteStringValue(enumValue);
{
writer.WriteNumberValue((int)(object)value);
}
}

private string GetEnumValue(Enum value)
private bool TryGetEnumValue(Enum value, out string outValue)
{
var field = value.GetType().GetField(value.ToString());

return field.GetCustomAttribute<JsonEnumValueAttribute>() is JsonEnumValueAttribute attribute
if (field == null)
{
outValue = null;
return false;
}

outValue = field.GetCustomAttribute<JsonEnumValueAttribute>() is JsonEnumValueAttribute attribute
? attribute.Value
: value.ToString();

return true;
}
}
}

0 comments on commit 099a765

Please sign in to comment.