Browse Source

Added support for enums to settings

ManlyMarco 5 years ago
parent
commit
795ab74fe0
1 changed files with 65 additions and 37 deletions
  1. 65 37
      BepInEx/Configuration/TomlTypeConverter.cs

+ 65 - 37
BepInEx/Configuration/TomlTypeConverter.cs

@@ -6,8 +6,8 @@ namespace BepInEx.Configuration
 {
 	public class TypeConverter
 	{
-		public Func<object, string> ConvertToString { get; set; }
-		public Func<string, object> ConvertToObject { get; set; }
+		public Func<object, Type, string> ConvertToString { get; set; }
+		public Func<string, Type, object> ConvertToObject { get; set; }
 	}
 
 	internal static class TomlTypeConverter
@@ -16,98 +16,126 @@ namespace BepInEx.Configuration
 		{
 			[typeof(string)] = new TypeConverter
 			{
-				ConvertToString = (obj) => (string)obj,
-				ConvertToObject = (str) => str,
+				ConvertToString = (obj, type) => (string)obj,
+				ConvertToObject = (str, type) => str,
 			},
 			[typeof(bool)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString().ToLowerInvariant(),
-				ConvertToObject = (str) => bool.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString().ToLowerInvariant(),
+				ConvertToObject = (str, type) => bool.Parse(str),
 			},
 			[typeof(byte)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => byte.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => byte.Parse(str),
 			},
 
 			//integral types
 
 			[typeof(sbyte)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => sbyte.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => sbyte.Parse(str),
 			},
 			[typeof(byte)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => byte.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => byte.Parse(str),
 			},
 			[typeof(short)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => short.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => short.Parse(str),
 			},
 			[typeof(ushort)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => ushort.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => ushort.Parse(str),
 			},
 			[typeof(int)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => int.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => int.Parse(str),
 			},
 			[typeof(uint)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => uint.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => uint.Parse(str),
 			},
 			[typeof(long)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => long.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => long.Parse(str),
 			},
 			[typeof(ulong)] = new TypeConverter
 			{
-				ConvertToString = (obj) => obj.ToString(),
-				ConvertToObject = (str) => ulong.Parse(str),
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => ulong.Parse(str),
 			},
 
 			//floating point types
 
 			[typeof(float)] = new TypeConverter
 			{
-				ConvertToString = (obj) => ((float)obj).ToString(NumberFormatInfo.InvariantInfo),
-				ConvertToObject = (str) => float.Parse(str, NumberFormatInfo.InvariantInfo),
+				ConvertToString = (obj, type) => ((float)obj).ToString(NumberFormatInfo.InvariantInfo),
+				ConvertToObject = (str, type) => float.Parse(str, NumberFormatInfo.InvariantInfo),
 			},
 			[typeof(double)] = new TypeConverter
 			{
-				ConvertToString = (obj) => ((double)obj).ToString(NumberFormatInfo.InvariantInfo),
-				ConvertToObject = (str) => double.Parse(str, NumberFormatInfo.InvariantInfo),
+				ConvertToString = (obj, type) => ((double)obj).ToString(NumberFormatInfo.InvariantInfo),
+				ConvertToObject = (str, type) => double.Parse(str, NumberFormatInfo.InvariantInfo),
 			},
 			[typeof(decimal)] = new TypeConverter
 			{
-				ConvertToString = (obj) => ((decimal)obj).ToString(NumberFormatInfo.InvariantInfo),
-				ConvertToObject = (str) => decimal.Parse(str, NumberFormatInfo.InvariantInfo),
+				ConvertToString = (obj, type) => ((decimal)obj).ToString(NumberFormatInfo.InvariantInfo),
+				ConvertToObject = (str, type) => decimal.Parse(str, NumberFormatInfo.InvariantInfo),
+			},
+
+			[typeof(Enum)] = new TypeConverter
+			{
+				ConvertToString = (obj, type) => obj.ToString(),
+				ConvertToObject = (str, type) => Enum.Parse(type, str, true),
 			},
 		};
 
-		public static string ConvertToString(object value)
+		public static string ConvertToString<T>(T value)
 		{
-			Type valueType = value.GetType();
+			var valueType = typeof(T);
 
-			if (!TypeConverters.ContainsKey(valueType))
+			var conv = GetConverter(valueType);
+			if (conv == null)
 				throw new InvalidOperationException($"Cannot convert from type {valueType}");
 
-			return TypeConverters[valueType].ConvertToString(value);
+			return conv.ConvertToString(value, valueType);
 		}
 
 		public static T ConvertToValue<T>(string value)
 		{
-			if (!TypeConverters.ContainsKey(typeof(T)))
-				throw new InvalidOperationException($"Cannot convert to type {typeof(T)}");
+			var valueType = typeof(T);
+
+			var conv = GetConverter(valueType);
+			if (conv == null)
+				throw new InvalidOperationException($"Cannot convert to type {valueType}");
+
+			return (T)conv.ConvertToObject(value, valueType);
+		}
+
+		private static TypeConverter GetConverter(Type valueType)
+		{
+			if (valueType.IsEnum)
+				return TypeConverters[typeof(Enum)];
+
+			return TypeConverters[valueType];
+		}
 
-			return (T)TypeConverters[typeof(T)].ConvertToObject(value);
+		public static bool CanConvert(Type type)
+		{
+			return GetConverter(type) != null;
+		}
+
+		public static IEnumerable<Type> GetSupportedTypes()
+		{
+			return TypeConverters.Keys;
 		}
 	}
 }