|
1 | 1 | using System; |
2 | 2 | using System.Collections; |
3 | 3 | using System.Collections.Generic; |
| 4 | +using System.Globalization; |
4 | 5 | using System.Linq; |
5 | 6 | using System.Reflection; |
6 | 7 | using Tomlet.Attributes; |
7 | 8 | using Tomlet.Exceptions; |
| 9 | +using Tomlet.Extensions; |
8 | 10 | using Tomlet.Models; |
9 | 11 |
|
10 | 12 | namespace Tomlet |
11 | 13 | { |
12 | 14 | public static class TomlSerializationMethods |
13 | 15 | { |
14 | 16 | private static MethodInfo _stringKeyedDictionaryMethod = typeof(TomlSerializationMethods).GetMethod(nameof(StringKeyedDictionaryDeserializerFor), BindingFlags.Static | BindingFlags.NonPublic)!; |
| 17 | + private static MethodInfo _primitiveKeyedDictionaryMethod = typeof(TomlSerializationMethods).GetMethod(nameof(PrimitiveKeyedDictionaryDeserializerFor), BindingFlags.Static | BindingFlags.NonPublic)!; |
15 | 18 | private static MethodInfo _genericDictionarySerializerMethod = typeof(TomlSerializationMethods).GetMethod(nameof(GenericDictionarySerializer), BindingFlags.Static | BindingFlags.NonPublic)!; |
16 | 19 | private static MethodInfo _genericNullableSerializerMethod = typeof(TomlSerializationMethods).GetMethod(nameof(GenericNullableSerializer), BindingFlags.Static | BindingFlags.NonPublic)!; |
17 | 20 |
|
@@ -195,6 +198,12 @@ internal static Deserialize<object> GetDeserializer(Type t, TomlSerializerOption |
195 | 198 | { |
196 | 199 | return (Deserialize<object>)_stringKeyedDictionaryMethod.MakeGenericMethod(genericArgs[1]).Invoke(null, new object[]{options})!; |
197 | 200 | } |
| 201 | + |
| 202 | + if (genericArgs[0].IsIntegerType() || genericArgs[0] == typeof(bool) || genericArgs[0] == typeof(char)) |
| 203 | + { |
| 204 | + // float primitives not supported due to decimal point causing issues |
| 205 | + return (Deserialize<object>)_primitiveKeyedDictionaryMethod.MakeGenericMethod(genericArgs).Invoke(null, new object[]{options})!; |
| 206 | + } |
198 | 207 | } |
199 | 208 |
|
200 | 209 | return TomlCompositeDeserializer.For(t, options); |
@@ -279,7 +288,24 @@ private static Deserialize<Dictionary<string, T>> StringKeyedDictionaryDeseriali |
279 | 288 | return table.Entries.ToDictionary(entry => entry.Key, entry => (T)deserializer(entry.Value)); |
280 | 289 | }; |
281 | 290 | } |
282 | | - |
| 291 | + |
| 292 | + // unmanaged + IConvertible is the closest I can get to expressing "primitives only" |
| 293 | + private static Deserialize<Dictionary<TKey, TValue>> PrimitiveKeyedDictionaryDeserializerFor<TKey, TValue>(TomlSerializerOptions options) where TKey : unmanaged, IConvertible |
| 294 | + { |
| 295 | + var valueDeserializer = GetDeserializer(typeof(TValue), options); |
| 296 | + |
| 297 | + return value => |
| 298 | + { |
| 299 | + if (value is not TomlTable table) |
| 300 | + throw new TomlTypeMismatchException(typeof(TomlTable), value.GetType(), typeof(Dictionary<TKey, TValue>)); |
| 301 | + |
| 302 | + return table.Entries.ToDictionary( |
| 303 | + entry => (TKey)(entry.Key as IConvertible).ToType(typeof(TKey), CultureInfo.InvariantCulture), |
| 304 | + entry => (TValue)valueDeserializer(entry.Value) |
| 305 | + ); |
| 306 | + }; |
| 307 | + } |
| 308 | + |
283 | 309 | private static TomlValue? GenericNullableSerializer<T>(T? nullable, TomlSerializerOptions options) where T : struct |
284 | 310 | { |
285 | 311 | var elementSerializer = GetSerializer(typeof(T), options); |
|
0 commit comments