Files
runner/src/Sdk/PipelinesWebApi/UnknownEnumJsonConverter.cs
2022-07-22 11:21:04 -04:00

55 lines
2.0 KiB
C#

using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace GitHub.Actions.Pipelines.WebApi
{
public class UnknownEnumJsonConverter : StringEnumConverter
{
public UnknownEnumJsonConverter()
{
this.NamingStrategy = new CamelCaseNamingStrategy();
}
public override bool CanConvert(Type objectType)
{
// we require one member to be named "Unknown"
return objectType.IsEnum && Enum.GetNames(objectType).Any(name => string.Equals(name, UnknownName, StringComparison.OrdinalIgnoreCase));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Newtonsoft doesn't call CanConvert if you specify the converter using a JsonConverter attribute
// they just assume you know what you're doing :)
if (!CanConvert(objectType))
{
// if there's no Unknown value, fall back to the StringEnumConverter behavior
return base.ReadJson(reader, objectType, existingValue, serializer);
}
if (reader.TokenType == JsonToken.Integer)
{
var intValue = Convert.ToInt32(reader.Value);
var values = (int[])Enum.GetValues(objectType);
if (values.Contains(intValue))
{
return Enum.Parse(objectType, intValue.ToString());
}
}
if (reader.TokenType == JsonToken.String)
{
var stringValue = reader.Value.ToString();
return UnknownEnum.Parse(objectType, stringValue);
}
// we know there's an Unknown value because CanConvert returned true
return Enum.Parse(objectType, UnknownName);
}
private const string UnknownName = "Unknown";
}
}