using IPA.Config.Data; using System; namespace IPA.Config.Stores.Converters { /// /// A for objects normally serialized to config via . /// /// the same type parameter that would be passed into /// public class CustomObjectConverter : ValueConverter where T : class { private interface IImpl { T FromValue(Value value, object parent); Value ToValue(T obj, object parent); } private class Impl : IImpl where U : class, GeneratedStore.IGeneratedStore, T { private static readonly GeneratedStore.GeneratedStoreCreator creator = GeneratedStore.GetCreator(typeof(T)); public T FromValue(Value value, object parent) { // lots of casting here, but it works i promise (probably) (parent can be a non-IGeneratedStore, however it won't necessarily behave then) var obj = creator(parent as GeneratedStore.IGeneratedStore) as U; obj.Deserialize(value); return obj; } public Value ToValue(T obj, object parent) { if (obj is GeneratedStore.IGeneratedStore store) return store.Serialize(); else return null; // TODO: make this behave sanely instead of just giving null } } private static readonly IImpl impl = (IImpl)Activator.CreateInstance( typeof(Impl<>).MakeGenericType(GeneratedStore.GetGeneratedType(typeof(T)))); /// /// Deserializes into a with the given . /// /// the to deserialize /// the parent object that will own the deserialized value /// the deserialized value /// public static T Deserialize(Value value, object parent) => impl.FromValue(value, parent); /// /// Serializes into a structure, given . /// /// the object to serialize /// the parent object that owns /// the tree that represents /// public static Value Serialize(T obj, object parent) => impl.ToValue(obj, parent); /// /// Deserializes into a with the given . /// /// the to deserialize /// the parent object that will own the deserialized value /// the deserialized value /// public override T FromValue(Value value, object parent) => impl.FromValue(value, parent); /// /// Serializes into a structure, given . /// /// the object to serialize /// the parent object that owns /// the tree that represents /// public override Value ToValue(T obj, object parent) => impl.ToValue(obj, parent); } }