40 lines
1.4 KiB
C#
40 lines
1.4 KiB
C#
using System.Text.Json;
|
|
|
|
/// <summary>
|
|
/// Shared read helper for converters that write DB-wire strings (e.g. "ICU")
|
|
/// but must also accept default System.Text.Json client payloads (numeric enums)
|
|
/// and PascalCase enum names.
|
|
/// </summary>
|
|
internal static class DbStringEnumJson
|
|
{
|
|
public static TEnum Read<TEnum>(ref Utf8JsonReader reader, Func<string, TEnum> fromDbString)
|
|
where TEnum : struct, Enum
|
|
{
|
|
switch (reader.TokenType)
|
|
{
|
|
case JsonTokenType.Number:
|
|
if (reader.TryGetInt32(out var numeric)
|
|
&& Enum.IsDefined(typeof(TEnum), numeric))
|
|
return (TEnum)Enum.ToObject(typeof(TEnum), numeric);
|
|
throw new JsonException($"Invalid numeric value for {typeof(TEnum).Name}.");
|
|
|
|
case JsonTokenType.String:
|
|
var raw = reader.GetString()
|
|
?? throw new JsonException($"Null string for {typeof(TEnum).Name}.");
|
|
try
|
|
{
|
|
return fromDbString(raw);
|
|
}
|
|
catch (ArgumentOutOfRangeException) when (
|
|
Enum.TryParse(raw, ignoreCase: true, out TEnum byName))
|
|
{
|
|
return byName;
|
|
}
|
|
|
|
default:
|
|
throw new JsonException(
|
|
$"Unexpected token {reader.TokenType} when parsing {typeof(TEnum).Name}.");
|
|
}
|
|
}
|
|
}
|