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.

121 lines
4.9 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace IPA.Config.Stores.Attributes
  7. {
  8. /// <summary>
  9. /// Causes a field or property in an object being wrapped by <see cref="GeneratedExtension.Generated{T}(Config, bool)"/> to be
  10. /// ignored during serialization and deserialization.
  11. /// </summary>
  12. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  13. public sealed class IgnoreAttribute : Attribute { }
  14. /// <summary>
  15. /// Indicates that a field or property in an object being wrapped by <see cref="GeneratedExtension.Generated{T}(Config, bool)"/>
  16. /// that would otherwise be nullable (i.e. a reference type or a <see cref="Nullable{T}"/> type) should never be null, and the
  17. /// member will be ignored if the deserialized value is <see langword="null"/>.
  18. /// </summary>
  19. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  20. public sealed class NonNullableAttribute : Attribute { }
  21. /// <summary>
  22. /// Indicates that a given field or property in an object being wrapped by <see cref="GeneratedExtension.Generated{T}(Config, bool)"/>
  23. /// should be serialized and deserialized using the provided converter instead of the default mechanism.
  24. /// </summary>
  25. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  26. public sealed class UseConverterAttribute : Attribute
  27. {
  28. /// <summary>
  29. /// Gets the type of the converter to use.
  30. /// </summary>
  31. public Type ConverterType { get; }
  32. /// <summary>
  33. /// Gets the target type of the converter if it is avaliable at instantiation time, otherwise
  34. /// <see langword="null"/>.
  35. /// </summary>
  36. public Type ConverterTargetType { get; }
  37. /// <summary>
  38. /// Gets whether or not this converter is a generic <see cref="ValueConverter{T}"/>.
  39. /// </summary>
  40. public bool IsGenericConverter => ConverterTargetType != null;
  41. /// <summary>
  42. /// Creates a new <see cref="UseConverterAttribute"/> with a given <see cref="ConverterType"/>.
  43. /// </summary>
  44. /// <param name="converterType">the type to assign to <see cref="ConverterType"/></param>
  45. public UseConverterAttribute(Type converterType)
  46. {
  47. ConverterType = converterType;
  48. var baseT = ConverterType.BaseType;
  49. while (baseT != null && baseT != typeof(object) &&
  50. (!baseT.IsGenericType || baseT.GetGenericTypeDefinition() != typeof(ValueConverter<>)))
  51. baseT = baseT.BaseType;
  52. if (baseT == typeof(object)) ConverterTargetType = null;
  53. else ConverterTargetType = baseT.GetGenericArguments()[0];
  54. var implInterface = ConverterType.GetInterfaces().Contains(typeof(IValueConverter));
  55. if (ConverterTargetType == null && !implInterface) throw new ArgumentException("Type is not a value converter!");
  56. }
  57. }
  58. /// <summary>
  59. /// Specifies a name for the serialized field or property in an object being wrapped by
  60. /// <see cref="GeneratedExtension.Generated{T}(Config, bool)"/> that is different from the member name itself.
  61. /// </summary>
  62. /// <example>
  63. /// <para>
  64. /// When serializing the following object, we might get the JSON that follows.
  65. /// <code>
  66. /// public class PluginConfig
  67. /// {
  68. /// public virtual bool BooleanField { get; set; } = true;
  69. /// }
  70. /// </code>
  71. /// <code>
  72. /// {
  73. /// "BooleanField": true
  74. /// }
  75. /// </code>
  76. /// </para>
  77. /// <para>
  78. /// However, if we were to add a <see cref="SerializedNameAttribute"/> to that field, we would get the following.
  79. /// <code>
  80. /// public class PluginConfig
  81. /// {
  82. /// [SerializedName("bool")]
  83. /// public virtual bool BooleanField { get; set; } = true;
  84. /// }
  85. /// </code>
  86. /// <code>
  87. /// {
  88. /// "bool": true
  89. /// }
  90. /// </code>
  91. /// </para>
  92. /// </example>
  93. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  94. public sealed class SerializedNameAttribute : Attribute
  95. {
  96. /// <summary>
  97. /// Gets the name to replace the member name with.
  98. /// </summary>
  99. public string Name { get; private set; }
  100. /// <summary>
  101. /// Creates a new <see cref="SerializedNameAttribute"/> with the given <see cref="Name"/>.
  102. /// </summary>
  103. /// <param name="name">the value to assign to <see cref="Name"/></param>
  104. public SerializedNameAttribute(string name)
  105. {
  106. Name = name;
  107. }
  108. }
  109. }