You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
4.1 KiB

  1. using IPA.Config.Data;
  2. using System;
  3. namespace IPA.Config.Stores.Converters
  4. {
  5. /// <summary>
  6. /// A <see cref="ValueConverter{T}"/> for objects normally serialized to config via <see cref="GeneratedExtension.Generated{T}(Config, bool)"/>.
  7. /// </summary>
  8. /// <typeparam name="T">the same type parameter that would be passed into <see cref="GeneratedExtension.Generated{T}(Config, bool)"/></typeparam>
  9. /// <seealso cref="GeneratedExtension.Generated{T}(Config, bool)"/>
  10. public class CustomObjectConverter<T> : ValueConverter<T> where T : class
  11. {
  12. private interface IImpl
  13. {
  14. T FromValue(Value value, object parent);
  15. Value ToValue(T obj, object parent);
  16. }
  17. private class Impl<U> : IImpl where U : class, GeneratedStore.IGeneratedStore, T
  18. {
  19. private static readonly GeneratedStore.GeneratedStoreCreator creator = GeneratedStore.GetCreator(typeof(T));
  20. public T FromValue(Value value, object parent)
  21. { // lots of casting here, but it works i promise (probably) (parent can be a non-IGeneratedStore, however it won't necessarily behave then)
  22. var obj = creator(parent as GeneratedStore.IGeneratedStore) as U;
  23. obj.Deserialize(value);
  24. return obj;
  25. }
  26. public Value ToValue(T obj, object parent)
  27. {
  28. if (obj is GeneratedStore.IGeneratedStore store)
  29. return store.Serialize();
  30. else
  31. return null; // TODO: make this behave sanely instead of just giving null
  32. }
  33. }
  34. private static readonly IImpl impl = (IImpl)Activator.CreateInstance(
  35. typeof(Impl<>).MakeGenericType(GeneratedStore.GetGeneratedType(typeof(T))));
  36. /// <summary>
  37. /// Deserializes <paramref name="value"/> into a <typeparamref name="T"/> with the given <paramref name="parent"/>.
  38. /// </summary>
  39. /// <param name="value">the <see cref="Value"/> to deserialize</param>
  40. /// <param name="parent">the parent object that will own the deserialized value</param>
  41. /// <returns>the deserialized value</returns>
  42. /// <seealso cref="ValueConverter{T}.FromValue(Value, object)"/>
  43. public static T Deserialize(Value value, object parent)
  44. => impl.FromValue(value, parent);
  45. /// <summary>
  46. /// Serializes <paramref name="obj"/> into a <see cref="Value"/> structure, given <paramref name="parent"/>.
  47. /// </summary>
  48. /// <param name="obj">the object to serialize</param>
  49. /// <param name="parent">the parent object that owns <paramref name="obj"/></param>
  50. /// <returns>the <see cref="Value"/> tree that represents <paramref name="obj"/></returns>
  51. /// <seealso cref="ValueConverter{T}.ToValue(T, object)"/>
  52. public static Value Serialize(T obj, object parent)
  53. => impl.ToValue(obj, parent);
  54. /// <summary>
  55. /// Deserializes <paramref name="value"/> into a <typeparamref name="T"/> with the given <paramref name="parent"/>.
  56. /// </summary>
  57. /// <param name="value">the <see cref="Value"/> to deserialize</param>
  58. /// <param name="parent">the parent object that will own the deserialized value</param>
  59. /// <returns>the deserialized value</returns>
  60. /// <seealso cref="ValueConverter{T}.FromValue(Value, object)"/>
  61. public override T FromValue(Value value, object parent)
  62. => impl.FromValue(value, parent);
  63. /// <summary>
  64. /// Serializes <paramref name="obj"/> into a <see cref="Value"/> structure, given <paramref name="parent"/>.
  65. /// </summary>
  66. /// <param name="obj">the object to serialize</param>
  67. /// <param name="parent">the parent object that owns <paramref name="obj"/></param>
  68. /// <returns>the <see cref="Value"/> tree that represents <paramref name="obj"/></returns>
  69. /// <seealso cref="ValueConverter{T}.ToValue(T, object)"/>
  70. public override Value ToValue(T obj, object parent)
  71. => impl.ToValue(obj, parent);
  72. }
  73. }