TomlTypeConverter.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. namespace BepInEx.Configuration
  5. {
  6. public class TypeConverter
  7. {
  8. public Func<object, Type, string> ConvertToString { get; set; }
  9. public Func<string, Type, object> ConvertToObject { get; set; }
  10. }
  11. internal static class TomlTypeConverter
  12. {
  13. public static Dictionary<Type, TypeConverter> TypeConverters { get; } = new Dictionary<Type, TypeConverter>
  14. {
  15. [typeof(string)] = new TypeConverter
  16. {
  17. ConvertToString = (obj, type) => (string)obj,
  18. ConvertToObject = (str, type) => str,
  19. },
  20. [typeof(bool)] = new TypeConverter
  21. {
  22. ConvertToString = (obj, type) => obj.ToString().ToLowerInvariant(),
  23. ConvertToObject = (str, type) => bool.Parse(str),
  24. },
  25. [typeof(byte)] = new TypeConverter
  26. {
  27. ConvertToString = (obj, type) => obj.ToString(),
  28. ConvertToObject = (str, type) => byte.Parse(str),
  29. },
  30. //integral types
  31. [typeof(sbyte)] = new TypeConverter
  32. {
  33. ConvertToString = (obj, type) => obj.ToString(),
  34. ConvertToObject = (str, type) => sbyte.Parse(str),
  35. },
  36. [typeof(byte)] = new TypeConverter
  37. {
  38. ConvertToString = (obj, type) => obj.ToString(),
  39. ConvertToObject = (str, type) => byte.Parse(str),
  40. },
  41. [typeof(short)] = new TypeConverter
  42. {
  43. ConvertToString = (obj, type) => obj.ToString(),
  44. ConvertToObject = (str, type) => short.Parse(str),
  45. },
  46. [typeof(ushort)] = new TypeConverter
  47. {
  48. ConvertToString = (obj, type) => obj.ToString(),
  49. ConvertToObject = (str, type) => ushort.Parse(str),
  50. },
  51. [typeof(int)] = new TypeConverter
  52. {
  53. ConvertToString = (obj, type) => obj.ToString(),
  54. ConvertToObject = (str, type) => int.Parse(str),
  55. },
  56. [typeof(uint)] = new TypeConverter
  57. {
  58. ConvertToString = (obj, type) => obj.ToString(),
  59. ConvertToObject = (str, type) => uint.Parse(str),
  60. },
  61. [typeof(long)] = new TypeConverter
  62. {
  63. ConvertToString = (obj, type) => obj.ToString(),
  64. ConvertToObject = (str, type) => long.Parse(str),
  65. },
  66. [typeof(ulong)] = new TypeConverter
  67. {
  68. ConvertToString = (obj, type) => obj.ToString(),
  69. ConvertToObject = (str, type) => ulong.Parse(str),
  70. },
  71. //floating point types
  72. [typeof(float)] = new TypeConverter
  73. {
  74. ConvertToString = (obj, type) => ((float)obj).ToString(NumberFormatInfo.InvariantInfo),
  75. ConvertToObject = (str, type) => float.Parse(str, NumberFormatInfo.InvariantInfo),
  76. },
  77. [typeof(double)] = new TypeConverter
  78. {
  79. ConvertToString = (obj, type) => ((double)obj).ToString(NumberFormatInfo.InvariantInfo),
  80. ConvertToObject = (str, type) => double.Parse(str, NumberFormatInfo.InvariantInfo),
  81. },
  82. [typeof(decimal)] = new TypeConverter
  83. {
  84. ConvertToString = (obj, type) => ((decimal)obj).ToString(NumberFormatInfo.InvariantInfo),
  85. ConvertToObject = (str, type) => decimal.Parse(str, NumberFormatInfo.InvariantInfo),
  86. },
  87. [typeof(Enum)] = new TypeConverter
  88. {
  89. ConvertToString = (obj, type) => obj.ToString(),
  90. ConvertToObject = (str, type) => Enum.Parse(type, str, true),
  91. },
  92. };
  93. public static string ConvertToString(object value, Type valueType)
  94. {
  95. var conv = GetConverter(valueType);
  96. if (conv == null)
  97. throw new InvalidOperationException($"Cannot convert from type {valueType}");
  98. return conv.ConvertToString(value, valueType);
  99. }
  100. public static T ConvertToValue<T>(string value)
  101. {
  102. return (T)ConvertToValue(value, typeof(T));
  103. }
  104. public static object ConvertToValue(string value, Type valueType)
  105. {
  106. var conv = GetConverter(valueType);
  107. if (conv == null)
  108. throw new InvalidOperationException($"Cannot convert to type {valueType}");
  109. return conv.ConvertToObject(value, valueType);
  110. }
  111. private static TypeConverter GetConverter(Type valueType)
  112. {
  113. if (valueType.IsEnum)
  114. return TypeConverters[typeof(Enum)];
  115. return TypeConverters[valueType];
  116. }
  117. public static bool CanConvert(Type type)
  118. {
  119. return GetConverter(type) != null;
  120. }
  121. public static IEnumerable<Type> GetSupportedTypes()
  122. {
  123. return TypeConverters.Keys;
  124. }
  125. }
  126. }