using IPA.Config.Data; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IPA.Config.Stores.Converters { /// /// Provides utility functions for custom converters. /// public static class Converter { /// /// Gets the integral value of a , coercing a if necessary, /// or if is not an or . /// /// the to get the integral value of /// the integral value of , or public static long? IntValue(Value val) => val is Integer inte ? inte.Value : val is FloatingPoint fp ? fp.AsInteger()?.Value : null; /// /// Gets the floaing point value of a , coercing an if necessary, /// or if is not an or . /// /// the to get the floaing point value of /// the floaing point value of , or public static decimal? FloatValue(Value val) => val is FloatingPoint fp ? fp.Value : val is Integer inte ? inte.AsFloat()?.Value : null; } 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 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)))); public static T Deserialize(Value value, object parent) => impl.FromValue(value, parent); public static Value Serialize(T obj, object parent) => impl.ToValue(obj, parent); public override T FromValue(Value value, object parent) => impl.FromValue(value, parent); public override Value ToValue(T obj, object parent) => impl.ToValue(obj, parent); } }