Skip to content

Commit 0a48f7a

Browse files
committed
Refactor object inference in JSON converter
Replaces switch on JsonTokenType with a recursive method using JsonElement.ValueKind for more robust and accurate type inference. This improves handling of nested objects and arrays, and unifies the logic for converting JSON values to .NET types.
1 parent 8eace11 commit 0a48f7a

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

templates/dotnet/Package/Converters/ObjectToInferredTypesConverter.cs.twig

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,60 @@ namespace {{ spec.title | caseUcfirst }}.Converters
77
{
88
public class ObjectToInferredTypesConverter : JsonConverter<object>
99
{
10-
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
10+
public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
1111
{
12-
switch (reader.TokenType)
12+
using (JsonDocument document = JsonDocument.ParseValue(ref reader))
1313
{
14-
case JsonTokenType.True:
15-
return true;
16-
case JsonTokenType.False:
17-
return false;
18-
case JsonTokenType.Number:
19-
if (reader.TryGetInt64(out long l))
14+
return ConvertElement(document.RootElement);
15+
}
16+
}
17+
18+
private object? ConvertElement(JsonElement element)
19+
{
20+
switch (element.ValueKind)
21+
{
22+
case JsonValueKind.Object:
23+
var dictionary = new Dictionary<string, object?>();
24+
foreach (var property in element.EnumerateObject())
2025
{
21-
return l;
26+
dictionary[property.Name] = ConvertElement(property.Value);
27+
}
28+
return dictionary;
29+
30+
case JsonValueKind.Array:
31+
var list = new List<object?>();
32+
foreach (var item in element.EnumerateArray())
33+
{
34+
list.Add(ConvertElement(item));
2235
}
23-
return reader.GetDouble();
24-
case JsonTokenType.String:
25-
if (reader.TryGetDateTime(out DateTime datetime))
36+
return list;
37+
38+
case JsonValueKind.String:
39+
if (element.TryGetDateTime(out DateTime datetime))
2640
{
2741
return datetime;
2842
}
29-
return reader.GetString()!;
30-
case JsonTokenType.StartObject:
31-
return JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options)!;
32-
case JsonTokenType.StartArray:
33-
return JsonSerializer.Deserialize<object[]>(ref reader, options)!;
43+
return element.GetString();
44+
45+
case JsonValueKind.Number:
46+
if (element.TryGetInt64(out long l))
47+
{
48+
return l;
49+
}
50+
return element.GetDouble();
51+
52+
case JsonValueKind.True:
53+
return true;
54+
55+
case JsonValueKind.False:
56+
return false;
57+
58+
case JsonValueKind.Null:
59+
case JsonValueKind.Undefined:
60+
return null;
61+
3462
default:
35-
return JsonDocument.ParseValue(ref reader).RootElement.Clone();
63+
throw new JsonException($"Unsupported JsonValueKind: {element.ValueKind}");
3664
}
3765
}
3866

0 commit comments

Comments
 (0)