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.

124 lines
5.2 KiB

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