diff --git a/MLEM.Data/Json/JsonConverters.cs b/MLEM.Data/Json/JsonConverters.cs
index 47e0543..184d29c 100644
--- a/MLEM.Data/Json/JsonConverters.cs
+++ b/MLEM.Data/Json/JsonConverters.cs
@@ -12,7 +12,7 @@ namespace MLEM.Data.Json {
/// An array of all of the s that are part of MLEM.Data
///
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().ToArray();
///
diff --git a/MLEM.Data/Json/StaticJsonConverter.cs b/MLEM.Data/Json/StaticJsonConverter.cs
new file mode 100644
index 0000000..be0a70a
--- /dev/null
+++ b/MLEM.Data/Json/StaticJsonConverter.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Newtonsoft.Json;
+
+namespace MLEM.Data.Json {
+ ///
+ /// A that doesn't actually serialize the object, but instead serializes the name given to it by the underlying .
+ /// Optionally, the name of a can be passed to this converter when used in the by passing the arguments for the constructor as .
+ ///
+ /// The type of the object to convert
+ public class StaticJsonConverter : JsonConverter {
+
+ private readonly Dictionary entries;
+ private readonly Dictionary inverse;
+
+ ///
+ /// Creates a new static json converter using the given underlying .
+ ///
+ /// The dictionary to use
+ public StaticJsonConverter(Dictionary entries) {
+ this.entries = entries;
+ this.inverse = entries.ToDictionary(kv => kv.Value, kv => kv.Key);
+ }
+
+ ///
+ /// Creates a new static json converter by finding the underlying from the given type and member name
+ ///
+ /// The name of the type that the dictionary is in
+ /// The name of the dictionary itself
+ public StaticJsonConverter(string typeName, string memberName) :
+ this(GetEntries(typeName, memberName)) {
+ }
+
+ ///
+ 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);
+ }
+
+ ///
+ 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 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 ?? throw new InvalidCastException($"{value} is not of expected type {typeof(T)}");
+ }
+
+ }
+}
\ No newline at end of file