#nullable enable
using IPA.Config.Stores.Converters;
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace IPA.Config.Stores.Attributes
{
///
/// Indicates that the generated subclass of the attribute's target should implement .
/// If the type this is applied to already inherits it, this is implied.
///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class NotifyPropertyChangesAttribute : Attribute { }
///
/// Causes a field or property in an object being wrapped by to be
/// ignored during serialization and deserialization.
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class IgnoreAttribute : Attribute { }
///
/// Indicates that a field or property in an object being wrapped by
/// that would otherwise be nullable (i.e. a reference type or a type) should never be null, and the
/// member will be ignored if the deserialized value is .
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class NonNullableAttribute : Attribute { }
///
/// Indicates that a given field or property in an object being wrapped by
/// should be serialized and deserialized using the provided converter instead of the default mechanism.
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class UseConverterAttribute : Attribute
{
///
/// Gets whether or not to use the default converter for the member type instead of the specified type.
///
[MemberNotNullWhen(false, nameof(ConverterType))]
public bool UseDefaultConverterForType { get; }
///
/// Gets the type of the converter to use.
///
public Type? ConverterType { get; }
///
/// Gets the target type of the converter if it is avaliable at instantiation time, otherwise
/// .
///
public Type? ConverterTargetType { get; }
///
/// Gets whether or not this converter is a generic .
///
[MemberNotNullWhen(true, nameof(ConverterTargetType))]
public bool IsGenericConverter => ConverterTargetType is not null;
///
/// Creates a new specifying to use the default converter type for the target member.
///
public UseConverterAttribute()
=> UseDefaultConverterForType = true;
///
/// Creates a new with a given .
///
/// the type to assign to
public UseConverterAttribute(Type converterType)
{
if (converterType is null)
throw new ArgumentNullException(nameof(converterType));
UseDefaultConverterForType = false;
ConverterType = converterType;
if (converterType.IsValueType)
throw new ArgumentException("Type is not a value converter!");
var baseT = ConverterType.BaseType;
while (baseT != typeof(object) &&
(!baseT.IsGenericType || baseT.GetGenericTypeDefinition() != typeof(ValueConverter<>)))
baseT = baseT.BaseType;
if (baseT == typeof(object)) ConverterTargetType = null;
else ConverterTargetType = baseT.GetGenericArguments()[0];
var implInterface = ConverterType.GetInterfaces().Contains(typeof(IValueConverter));
if (ConverterTargetType == null && !implInterface) throw new ArgumentException("Type is not a value converter!");
}
}
///
/// Specifies a name for the serialized field or property in an object being wrapped by
/// that is different from the member name itself.
///
///
///
/// When serializing the following object, we might get the JSON that follows.
///
/// public class PluginConfig
/// {
/// public virtual bool BooleanField { get; set; } = true;
/// }
///
///
/// {
/// "BooleanField": true
/// }
///
///
///
/// However, if we were to add a to that field, we would get the following.
///
/// public class PluginConfig
/// {
/// [SerializedName("bool")]
/// public virtual bool BooleanField { get; set; } = true;
/// }
///
///
/// {
/// "bool": true
/// }
///
///
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class SerializedNameAttribute : Attribute
{
///
/// Gets the name to replace the member name with.
///
public string Name { get; private set; }
///
/// Creates a new with the given .
///
/// the value to assign to
public SerializedNameAttribute(string name)
{
Name = name;
}
}
}