Preparation fo Mystery rolling
This commit is contained in:
72
ALttPRandomizer/Serialization/YamlStringEnumConverter.cs
Normal file
72
ALttPRandomizer/Serialization/YamlStringEnumConverter.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace ALttPRandomizer.Serialization {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
public class YamlStringEnumConverter : IYamlTypeConverter {
|
||||
private readonly Dictionary<Type, Dictionary<string, object>> deserializationMap;
|
||||
private readonly Dictionary<Type, Dictionary<object, string>> serializationMap;
|
||||
|
||||
public YamlStringEnumConverter() {
|
||||
this.deserializationMap = new();
|
||||
this.serializationMap = new();
|
||||
}
|
||||
|
||||
public bool Accepts(Type type) => type.IsEnum;
|
||||
|
||||
private void RegisterType(Type type) {
|
||||
if (this.serializationMap.ContainsKey(type) && this.deserializationMap.ContainsKey(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.deserializationMap[type] = new();
|
||||
this.serializationMap[type] = new();
|
||||
|
||||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
foreach (var field in fields) {
|
||||
var alias = UnderscoredNamingConvention.Instance.Apply(field.Name);
|
||||
var value = Enum.Parse(type, field.Name);
|
||||
var att = field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>();
|
||||
if (att != null) {
|
||||
alias = att.Name;
|
||||
}
|
||||
|
||||
this.deserializationMap[type][alias] = value;
|
||||
this.serializationMap[type][value] = alias;
|
||||
}
|
||||
}
|
||||
|
||||
public object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) {
|
||||
this.RegisterType(type);
|
||||
|
||||
var stringValue = parser.Consume<Scalar>().Value;
|
||||
|
||||
if (this.deserializationMap[type].TryGetValue(stringValue, out var value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new YamlException($"Invalid value \"{stringValue}\" for type {type}");
|
||||
}
|
||||
|
||||
public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) {
|
||||
this.RegisterType(type);
|
||||
|
||||
if (value is null) {
|
||||
throw new YamlException($"Unexpected null value of type {type}");
|
||||
}
|
||||
|
||||
if (this.serializationMap[type].TryGetValue(value, out var stringValue)) {
|
||||
emitter.Emit(new Scalar(stringValue));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new YamlException($"Invalid value \"{value}\" for type {type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user