diff --git a/IPA.Loader/Config/Stores/Converters.cs b/IPA.Loader/Config/Stores/Converters.cs index 672019fa..b78c95b4 100644 --- a/IPA.Loader/Config/Stores/Converters.cs +++ b/IPA.Loader/Config/Stores/Converters.cs @@ -178,6 +178,93 @@ namespace IPA.Config.Stores.Converters public NullableConverter() : base(new TConverter()) { } } + /// + /// A converter for an enum of type , that converts the enum to its string representation and back. + /// + /// the enum type + public sealed class EnumConverter : ValueConverter + where T : Enum + { + /// + /// Converts a that is a node to the corresponding enum value. + /// + /// the to convert + /// the object which will own the created object + /// the deserialized enum value + /// if is not a node + public override T FromValue(Value value, object parent) + => value is Text t + ? (T)Enum.Parse(typeof(T), t.Value) + : throw new ArgumentException("Value not a string", nameof(value)); + + /// + /// Converts an enum of type to a node corresponding to its value. + /// + /// the value to serialize + /// the object which owns + /// a node representing + public override Value ToValue(T obj, object parent) + => Value.Text(obj.ToString()); + } + + /// + /// A converter for an enum of type , that converts the enum to its string representation and back, + /// ignoring the case of the serialized value for deseiralization. + /// + /// the enum type + public sealed class CaseInsensitiveEnumConverter : ValueConverter + where T : Enum + { + /// + /// Converts a that is a node to the corresponding enum value. + /// + /// the to convert + /// the object which will own the created object + /// the deserialized enum value + /// if is not a node + public override T FromValue(Value value, object parent) + => value is Text t + ? (T)Enum.Parse(typeof(T), t.Value, true) + : throw new ArgumentException("Value not a string", nameof(value)); + + /// + /// Converts an enum of type to a node corresponding to its value. + /// + /// the value to serialize + /// the object which owns + /// a node representing + public override Value ToValue(T obj, object parent) + => Value.Text(obj.ToString()); + } + + /// + /// A converter for an enum of type , that converts the enum to its underlying value for serialization. + /// + /// the enum type + public sealed class NumericEnumConverter : ValueConverter + where T : Enum + { + /// + /// Converts a that is a numeric node to the corresponding enum value. + /// + /// the to convert + /// the object which will own the created object + /// the deserialized enum value + /// if is not a numeric node + public override T FromValue(Value value, object parent) + => (T)Enum.ToObject(typeof(T), Converter.IntValue(value) + ?? throw new ArgumentException("Value not a numeric node", nameof(value))); + + /// + /// Converts an enum of type to a node corresponding to its value. + /// + /// the value to serialize + /// the object which owns + /// an node representing + public override Value ToValue(T obj, object parent) + => Value.Integer(Convert.ToInt64(obj)); + } + internal class StringConverter : ValueConverter { public override string FromValue(Value value, object parent) @@ -190,7 +277,8 @@ namespace IPA.Config.Stores.Converters internal class CharConverter : ValueConverter { public override char FromValue(Value value, object parent) - => (value as Text).Value[0]; // can throw nullptr + => (value as Text)?.Value[0] + ?? throw new ArgumentException("Value not a text node", nameof(value)); // can throw nullptr public override Value ToValue(char obj, object parent) => Value.From(char.ToString(obj)); @@ -199,7 +287,8 @@ namespace IPA.Config.Stores.Converters internal class LongConverter : ValueConverter { public override long FromValue(Value value, object parent) - => Converter.IntValue(value) ?? throw new ArgumentException("Value not a numeric value", nameof(value)); + => Converter.IntValue(value) + ?? throw new ArgumentException("Value not a numeric value", nameof(value)); public override Value ToValue(long obj, object parent) => Value.From(obj); @@ -208,7 +297,8 @@ namespace IPA.Config.Stores.Converters internal class ULongConverter : ValueConverter { public override ulong FromValue(Value value, object parent) - => (ulong)(Converter.FloatValue(value) ?? throw new ArgumentException("Value not a numeric value", nameof(value))); + => (ulong)(Converter.FloatValue(value) + ?? throw new ArgumentException("Value not a numeric value", nameof(value))); public override Value ToValue(ulong obj, object parent) => Value.From(obj); @@ -307,7 +397,7 @@ namespace IPA.Config.Stores.Converters internal class BooleanConverter : ValueConverter { public override bool FromValue(Value value, object parent) - => (value as Boolean).Value; + => (value as Boolean)?.Value ?? throw new ArgumentException("Value not a Boolean", nameof(value)); public override Value ToValue(bool obj, object parent) => Value.From(obj); }