Browse Source

Add config support for all value types

Bepis 5 years ago
parent
commit
ecda69edb7
2 changed files with 90 additions and 41 deletions
  1. 1 1
      BepInEx/Configuration/ConfigWrapper.cs
  2. 89 40
      BepInEx/Configuration/TomlTypeConverter.cs

+ 1 - 1
BepInEx/Configuration/ConfigWrapper.cs

@@ -29,7 +29,7 @@ namespace BepInEx.Configuration
 
 		public ConfigWrapper(ConfigFile configFile, ConfigDefinition definition)
 		{
-			if (!TomlTypeConverter.SupportedTypes.Contains(typeof(T)))
+			if (!TomlTypeConverter.TypeConverters.ContainsKey(typeof(T)))
 				throw new ArgumentException("Unsupported config wrapper type");
 
 			ConfigFile = configFile;

+ 89 - 40
BepInEx/Configuration/TomlTypeConverter.cs

@@ -1,63 +1,112 @@
 using System;
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
 
 namespace BepInEx.Configuration
 {
-	internal static class TomlTypeConverter
+	public class TypeConverter
 	{
-		public static ReadOnlyCollection<Type> SupportedTypes { get; } = new ReadOnlyCollection<Type>(new[]
-		{
-			typeof(string),
-			typeof(int),
-			typeof(bool)
-		});
+		public Func<object, string> ConvertToString { get; set; }
+		public Func<string, object> ConvertToObject { get; set; }
+	}
 
-		public static string ConvertToString(object value)
+	internal static class TomlTypeConverter
+	{
+		public static Dictionary<Type, TypeConverter> TypeConverters { get; } = new Dictionary<Type, TypeConverter>
 		{
-			Type valueType = value.GetType();
+			[typeof(string)] = new TypeConverter
+			{
+				ConvertToString = (obj) => (string)obj,
+				ConvertToObject = (str) => str,
+			},
+			[typeof(bool)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString().ToLowerInvariant(),
+				ConvertToObject = (str) => bool.Parse(str),
+			},
+			[typeof(byte)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => byte.Parse(str),
+			},
 
-			if (!SupportedTypes.Contains(valueType))
-				throw new InvalidOperationException($"Cannot convert from type {valueType}");
+			//integral types
 
-			if (value is string s)
+			[typeof(sbyte)] = new TypeConverter
 			{
-				return s;
-			}
-
-			if (value is int i)
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => sbyte.Parse(str),
+			},
+			[typeof(byte)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => byte.Parse(str),
+			},
+			[typeof(short)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => short.Parse(str),
+			},
+			[typeof(ushort)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => ushort.Parse(str),
+			},
+			[typeof(int)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => int.Parse(str),
+			},
+			[typeof(uint)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => uint.Parse(str),
+			},
+			[typeof(long)] = new TypeConverter
 			{
-				return i.ToString();
-			}
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => long.Parse(str),
+			},
+			[typeof(ulong)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => ulong.Parse(str),
+			},
+
+			//floating point types
 
-			if (value is bool b)
+			[typeof(float)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => float.Parse(str),
+			},
+			[typeof(double)] = new TypeConverter
+			{
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => double.Parse(str),
+			},
+			[typeof(decimal)] = new TypeConverter
 			{
-				return b.ToString().ToLowerInvariant();
-			}
+				ConvertToString = (obj) => obj.ToString(),
+				ConvertToObject = (str) => decimal.Parse(str),
+			},
+		};
+
+		public static string ConvertToString(object value)
+		{
+			Type valueType = value.GetType();
 
-			throw new NotImplementedException("Supported type does not have a converter");
+			if (!TypeConverters.ContainsKey(valueType))
+				throw new InvalidOperationException($"Cannot convert from type {valueType}");
+
+			return TypeConverters[valueType].ConvertToString(value);
 		}
 
 		public static T ConvertToValue<T>(string value)
 		{
-			if (!SupportedTypes.Contains(typeof(T)))
+			if (!TypeConverters.ContainsKey(typeof(T)))
 				throw new InvalidOperationException($"Cannot convert to type {typeof(T)}");
 
-			if (typeof(T) == typeof(string))
-			{
-				return (T)(object)value;
-			}
-
-			if (typeof(T) == typeof(int))
-			{
-				return (T)(object)int.Parse(value);
-			}
-
-			if (typeof(T) == typeof(bool))
-			{
-				return (T)(object)bool.Parse(value);
-			}
-
-			throw new NotImplementedException("Supported type does not have a converter");
+			return (T)TypeConverters[typeof(T)].ConvertToObject(value);
 		}
 	}
 }