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; } /// /// 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 (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); } }