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);
}