| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System.Diagnostics; |
| | | 5 | | using System.Diagnostics.CodeAnalysis; |
| | | 6 | | using System.Text.Json.Reflection; |
| | | 7 | | |
| | | 8 | | namespace System.Text.Json.Serialization.Converters |
| | | 9 | | { |
| | | 10 | | [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] |
| | | 11 | | internal sealed class EnumConverterFactory : JsonConverterFactory |
| | | 12 | | { |
| | 1 | 13 | | public EnumConverterFactory() |
| | 1 | 14 | | { |
| | 1 | 15 | | } |
| | | 16 | | |
| | | 17 | | public override bool CanConvert(Type type) |
| | 4184 | 18 | | { |
| | 4184 | 19 | | return type.IsEnum; |
| | 4184 | 20 | | } |
| | | 21 | | |
| | | 22 | | public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) |
| | 269 | 23 | | { |
| | 269 | 24 | | Debug.Assert(CanConvert(type)); |
| | 269 | 25 | | return Create(type, EnumConverterOptions.AllowNumbers, namingPolicy: null, options); |
| | 269 | 26 | | } |
| | | 27 | | |
| | | 28 | | [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2071:UnrecognizedReflectionPattern", |
| | | 29 | | Justification = "'EnumConverter<T> where T : struct' implies 'T : new()', so the trimmer is warning calling |
| | | 30 | | "But EnumConverter doesn't call new T(), so this is safe.")] |
| | | 31 | | public static JsonConverter Create(Type enumType, EnumConverterOptions converterOptions, JsonNamingPolicy? namin |
| | 538 | 32 | | { |
| | 538 | 33 | | if (!Helpers.IsSupportedTypeCode(Type.GetTypeCode(enumType))) |
| | 0 | 34 | | { |
| | | 35 | | // Char-backed enums are valid in IL and F# but are not supported by System.Text.Json. |
| | 0 | 36 | | return UnsupportedTypeConverterFactory.CreateUnsupportedConverterForType(enumType); |
| | | 37 | | } |
| | | 38 | | |
| | 538 | 39 | | Type converterType = typeof(EnumConverter<>).MakeGenericType(enumType); |
| | 538 | 40 | | return (JsonConverter)converterType.CreateInstanceNoWrapExceptions( |
| | 538 | 41 | | parameterTypes: [typeof(EnumConverterOptions), typeof(JsonNamingPolicy), typeof(JsonSerializerOptions)], |
| | 538 | 42 | | parameters: [converterOptions, namingPolicy, options])!; |
| | 538 | 43 | | } |
| | | 44 | | |
| | | 45 | | // Some of the static methods are in a separate class so that the |
| | | 46 | | // RequiresDynamicCode annotation on EnumConverterFactory doesn't apply |
| | | 47 | | // to them. |
| | | 48 | | internal static class Helpers |
| | | 49 | | { |
| | | 50 | | public static bool IsSupportedTypeCode(TypeCode typeCode) |
| | 1076 | 51 | | { |
| | 1076 | 52 | | return typeCode is TypeCode.SByte or TypeCode.Int16 or TypeCode.Int32 or TypeCode.Int64 |
| | 1076 | 53 | | or TypeCode.Byte or TypeCode.UInt16 or TypeCode.UInt32 or TypeCode.UInt64; |
| | 1076 | 54 | | } |
| | | 55 | | |
| | | 56 | | public static JsonConverter<T> Create<T>(EnumConverterOptions converterOptions, JsonSerializerOptions option |
| | | 57 | | where T : struct, Enum |
| | 0 | 58 | | { |
| | 0 | 59 | | if (!IsSupportedTypeCode(Type.GetTypeCode(typeof(T)))) |
| | 0 | 60 | | { |
| | | 61 | | // Char-backed enums are valid in IL and F# but are not supported by System.Text.Json. |
| | 0 | 62 | | return new UnsupportedTypeConverter<T>(); |
| | | 63 | | } |
| | | 64 | | |
| | 0 | 65 | | return new EnumConverter<T>(converterOptions, namingPolicy, options); |
| | 0 | 66 | | } |
| | | 67 | | } |
| | | 68 | | } |
| | | 69 | | } |