You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.3 KiB
74 lines
2.3 KiB
using System;
|
|
using YamlDotNet.Core;
|
|
using YamlDotNet.Core.Events;
|
|
using YamlDotNet.Serialization;
|
|
|
|
namespace Trash.YamlDotNet
|
|
{
|
|
// A workaround for nullable enums in YamlDotNet taken from:
|
|
// https://github.com/aaubry/YamlDotNet/issues/544#issuecomment-778062351
|
|
internal class YamlNullableEnumTypeConverter : IYamlTypeConverter
|
|
{
|
|
public bool Accepts(Type type)
|
|
{
|
|
return Nullable.GetUnderlyingType(type)?.IsEnum ?? false;
|
|
}
|
|
|
|
public object? ReadYaml(IParser parser, Type type)
|
|
{
|
|
type = Nullable.GetUnderlyingType(type) ??
|
|
throw new ArgumentException("Expected nullable enum type for ReadYaml");
|
|
|
|
if (parser.Accept<NodeEvent>(out var @event))
|
|
{
|
|
if (NodeIsNull(@event))
|
|
{
|
|
parser.SkipThisAndNestedEvents();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var scalar = parser.Consume<Scalar>();
|
|
try
|
|
{
|
|
return Enum.Parse(type, scalar.Value, true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"Invalid value: \"{scalar.Value}\" for {type.Name}", ex);
|
|
}
|
|
}
|
|
|
|
public void WriteYaml(IEmitter emitter, object? value, Type type)
|
|
{
|
|
type = Nullable.GetUnderlyingType(type) ??
|
|
throw new ArgumentException("Expected nullable enum type for WriteYaml");
|
|
|
|
if (value != null)
|
|
{
|
|
var toWrite = Enum.GetName(type, value) ??
|
|
throw new InvalidOperationException($"Invalid value {value} for enum: {type}");
|
|
emitter.Emit(new Scalar(null!, null!, toWrite, ScalarStyle.Any, true, false));
|
|
}
|
|
}
|
|
|
|
private static bool NodeIsNull(NodeEvent nodeEvent)
|
|
{
|
|
// http://yaml.org/type/null.html
|
|
|
|
if (nodeEvent.Tag == "tag:yaml.org,2002:null")
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (nodeEvent is Scalar scalar && scalar.Style == ScalarStyle.Plain)
|
|
{
|
|
var value = scalar.Value;
|
|
return value is "" or "~" or "null" or "Null" or "NULL";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|