File: System\Text\Json\Serialization\Converters\CastingConverter.cs
Web Access
Project: src\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json)
// 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.Diagnostics.CodeAnalysis;
using System.Text.Json.Nodes;
using System.Text.Json.Reflection;
using System.Text.Json.Schema;
 
namespace System.Text.Json.Serialization.Converters
{
    /// <summary>
    /// Converter wrapper which casts SourceType into TargetType
    /// </summary>
    internal sealed class CastingConverter<T> : JsonConverter<T>
    {
        private readonly JsonConverter _sourceConverter;
        internal override Type? KeyType => _sourceConverter.KeyType;
        internal override Type? ElementType => _sourceConverter.ElementType;
        internal override JsonConverter? NullableElementConverter => _sourceConverter.NullableElementConverter;
 
        public override bool HandleNull { get; }
        internal override bool SupportsCreateObjectDelegate => _sourceConverter.SupportsCreateObjectDelegate;
 
        internal CastingConverter(JsonConverter sourceConverter)
        {
            Debug.Assert(typeof(T).IsInSubtypeRelationshipWith(sourceConverter.Type!));
            Debug.Assert(sourceConverter.SourceConverterForCastingConverter is null, "casting converters should not be layered.");
 
            _sourceConverter = sourceConverter;
            IsInternalConverter = sourceConverter.IsInternalConverter;
            IsInternalConverterForNumberType = sourceConverter.IsInternalConverterForNumberType;
            ConverterStrategy = sourceConverter.ConverterStrategy;
            CanBePolymorphic = sourceConverter.CanBePolymorphic;
 
            // Ensure HandleNull values reflect the exact configuration of the source converter
            HandleNullOnRead = sourceConverter.HandleNullOnRead;
            HandleNullOnWrite = sourceConverter.HandleNullOnWrite;
            HandleNull = sourceConverter.HandleNullOnWrite;
        }
 
        internal override JsonConverter? SourceConverterForCastingConverter => _sourceConverter;
 
        public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            => JsonSerializer.UnboxOnRead<T>(_sourceConverter.ReadAsObject(ref reader, typeToConvert, options));
 
        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
            => _sourceConverter.WriteAsObject(writer, value, options);
 
        internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, scoped ref ReadStack state, out T? value)
        {
            bool result = _sourceConverter.OnTryReadAsObject(ref reader, typeToConvert, options, ref state, out object? sourceValue);
            value = JsonSerializer.UnboxOnRead<T>(sourceValue);
            return result;
        }
 
        internal override bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state)
            => _sourceConverter.OnTryWriteAsObject(writer, value, options, ref state);
 
        public override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            => JsonSerializer.UnboxOnRead<T>(_sourceConverter.ReadAsPropertyNameAsObject(ref reader, typeToConvert, options))!;
 
        internal override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            => JsonSerializer.UnboxOnRead<T>(_sourceConverter.ReadAsPropertyNameCoreAsObject(ref reader, typeToConvert, options))!;
 
        public override void WriteAsPropertyName(Utf8JsonWriter writer, [DisallowNull] T value, JsonSerializerOptions options)
            => _sourceConverter.WriteAsPropertyNameAsObject(writer, value, options);
 
        internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, JsonSerializerOptions options, bool isWritingExtensionDataProperty)
            => _sourceConverter.WriteAsPropertyNameCoreAsObject(writer, value, options, isWritingExtensionDataProperty);
 
        internal override T ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options)
            => JsonSerializer.UnboxOnRead<T>(_sourceConverter.ReadNumberWithCustomHandlingAsObject(ref reader, handling, options))!;
 
        internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T? value, JsonNumberHandling handling)
            => _sourceConverter.WriteNumberWithCustomHandlingAsObject(writer, value, handling);
 
        internal override JsonSchema? GetSchema(JsonNumberHandling numberHandling)
            => _sourceConverter.GetSchema(numberHandling);
    }
}