mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-25 17:59:24 +01:00
added StaticJsonConverter
This commit is contained in:
parent
37609ade76
commit
abcdcd21cc
2 changed files with 63 additions and 1 deletions
|
@ -12,7 +12,7 @@ namespace MLEM.Data.Json {
|
|||
/// An array of all of the <see cref="JsonConverter"/>s that are part of MLEM.Data
|
||||
/// </summary>
|
||||
public static readonly JsonConverter[] Converters = typeof(JsonConverters).Assembly.GetExportedTypes()
|
||||
.Where(t => t.IsSubclassOf(typeof(JsonConverter)))
|
||||
.Where(t => t.IsSubclassOf(typeof(JsonConverter)) && !t.IsGenericType)
|
||||
.Select(t => t.GetConstructor(Type.EmptyTypes).Invoke(null)).Cast<JsonConverter>().ToArray();
|
||||
|
||||
/// <summary>
|
||||
|
|
62
MLEM.Data/Json/StaticJsonConverter.cs
Normal file
62
MLEM.Data/Json/StaticJsonConverter.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <summary>
|
||||
/// A <see cref="JsonConverter{T}"/> that doesn't actually serialize the object, but instead serializes the name given to it by the underlying <see cref="Dictionary{T,T}"/>.
|
||||
/// Optionally, the name of a <see cref="Dictionary{TKey,TValue}"/> can be passed to this converter when used in the <see cref="JsonConverterAttribute"/> by passing the arguments for the <see cref="StaticJsonConverter{T}(string,string)"/> constructor as <see cref="JsonConverterAttribute.ConverterParameters"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to convert</typeparam>
|
||||
public class StaticJsonConverter<T> : JsonConverter<T> {
|
||||
|
||||
private readonly Dictionary<string, T> entries;
|
||||
private readonly Dictionary<T, string> inverse;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new static json converter using the given underlying <see cref="Dictionary{T,T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="entries">The dictionary to use</param>
|
||||
public StaticJsonConverter(Dictionary<string, T> entries) {
|
||||
this.entries = entries;
|
||||
this.inverse = entries.ToDictionary(kv => kv.Value, kv => kv.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new static json converter by finding the underlying <see cref="Dictionary{TKey,TValue}"/> from the given type and member name
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the type that the dictionary is in</param>
|
||||
/// <param name="memberName">The name of the dictionary itself</param>
|
||||
public StaticJsonConverter(string typeName, string memberName) :
|
||||
this(GetEntries(typeName, memberName)) {
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer) {
|
||||
if (!this.inverse.TryGetValue(value, out var key))
|
||||
throw new InvalidOperationException($"Cannot write {value} that is not a registered entry");
|
||||
writer.WriteValue(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var val = reader.Value?.ToString();
|
||||
if (val == null)
|
||||
return default;
|
||||
this.entries.TryGetValue(val, out var ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static Dictionary<string, T> GetEntries(string typeName, string memberName) {
|
||||
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
var type = Type.GetType(typeName) ?? throw new ArgumentException($"Type {typeName} does not exist", nameof(typeName));
|
||||
var value = type.GetProperty(memberName, flags)?.GetValue(null) ?? type.GetField(memberName, flags)?.GetValue(null);
|
||||
if (value == null)
|
||||
throw new ArgumentException($"There is no property or field value for name {memberName}", nameof(memberName));
|
||||
return value as Dictionary<string, T> ?? throw new InvalidCastException($"{value} is not of expected type {typeof(T)}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue