|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Text.Json.Nodes;
using System.Text.Json.Schema;
using System.Text.Json.Serialization.Metadata;
namespace System.Text.Json.Serialization.Converters
{
/// <summary>
/// Converter for JsonNode-derived types. The {T} value must be Object and not JsonNode
/// since we allow Object-declared members\variables to deserialize as {JsonNode}.
/// </summary>
internal sealed class JsonNodeConverter : JsonConverter<JsonNode?>
{
private static JsonNodeConverter? s_nodeConverter;
private static JsonArrayConverter? s_arrayConverter;
private static JsonObjectConverter? s_objectConverter;
private static JsonValueConverter? s_valueConverter;
public static JsonNodeConverter Instance => s_nodeConverter ??= new JsonNodeConverter();
public static JsonArrayConverter ArrayConverter => s_arrayConverter ??= new JsonArrayConverter();
public static JsonObjectConverter ObjectConverter => s_objectConverter ??= new JsonObjectConverter();
public static JsonValueConverter ValueConverter => s_valueConverter ??= new JsonValueConverter();
public override void Write(Utf8JsonWriter writer, JsonNode? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
value.WriteTo(writer, options);
}
}
public override JsonNode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
case JsonTokenType.False:
case JsonTokenType.True:
case JsonTokenType.Number:
return ValueConverter.Read(ref reader, typeToConvert, options);
case JsonTokenType.StartObject:
return ObjectConverter.Read(ref reader, typeToConvert, options);
case JsonTokenType.StartArray:
return ArrayConverter.Read(ref reader, typeToConvert, options);
case JsonTokenType.Null:
return null;
default:
Debug.Assert(false);
throw new JsonException();
}
}
public static JsonNode? Create(JsonElement element, JsonNodeOptions? options)
{
JsonNode? node;
switch (element.ValueKind)
{
case JsonValueKind.Null:
node = null;
break;
case JsonValueKind.Object:
node = new JsonObject(element, options);
break;
case JsonValueKind.Array:
node = new JsonArray(element, options);
break;
default:
node = new JsonValueOfElement(element, options);
break;
}
return node;
}
internal override JsonSchema? GetSchema(JsonNumberHandling _) => JsonSchema.True;
}
}
|