about summary refs log tree commit diff
path: root/LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs')
-rw-r--r--LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs112
1 files changed, 112 insertions, 0 deletions
diff --git a/LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs b/LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs
new file mode 100644
index 0000000..3b4c493
--- /dev/null
+++ b/LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs
@@ -0,0 +1,112 @@
+/*namespace LibMatrix.EventTypes.Converters;
+
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+public class MatrixEventConverter : JsonConverterFactory {
+    public override bool CanConvert(Type typeToConvert) {
+        Console.WriteLine(typeToConvert);
+        if (!typeToConvert.IsGenericType) {
+            return false;
+        }
+
+        if (typeToConvert.GetGenericTypeDefinition() != typeof(MatrixEvent<>)) {
+            return false;
+        }
+
+        return typeToConvert.GetGenericArguments()[0].IsAssignableTo(typeof(MatrixEventContent));
+    }
+
+    public override JsonConverter CreateConverter(
+        Type type,
+        JsonSerializerOptions options) {
+        Type[] typeArguments = type.GetGenericArguments();
+        Type keyType = typeArguments[0];
+        Type valueType = typeArguments[1];
+
+        JsonConverter converter = (JsonConverter)Activator.CreateInstance(
+            typeof(DictionaryEnumConverterInner<,>).MakeGenericType(
+                [keyType, valueType]),
+            BindingFlags.Instance | BindingFlags.Public,
+            binder: null,
+            args: [options],
+            culture: null)!;
+
+        return converter;
+    }
+
+    private class DictionaryEnumConverterInner<TKey, TValue> :
+        JsonConverter<Dictionary<TKey, TValue>> where TKey : struct, Enum {
+        private readonly JsonConverter<TValue> _valueConverter;
+        private readonly Type _keyType;
+        private readonly Type _valueType;
+
+        public DictionaryEnumConverterInner(JsonSerializerOptions options) {
+            // For performance, use the existing converter.
+            _valueConverter = (JsonConverter<TValue>)options
+                .GetConverter(typeof(TValue));
+
+            // Cache the key and value types.
+            _keyType = typeof(TKey);
+            _valueType = typeof(TValue);
+        }
+
+        public override Dictionary<TKey, TValue> Read(
+            ref Utf8JsonReader reader,
+            Type typeToConvert,
+            JsonSerializerOptions options) {
+            if (reader.TokenType != JsonTokenType.StartObject) {
+                throw new JsonException();
+            }
+
+            var dictionary = new Dictionary<TKey, TValue>();
+
+            while (reader.Read()) {
+                if (reader.TokenType == JsonTokenType.EndObject) {
+                    return dictionary;
+                }
+
+                // Get the key.
+                if (reader.TokenType != JsonTokenType.PropertyName) {
+                    throw new JsonException();
+                }
+
+                string? propertyName = reader.GetString();
+
+                // For performance, parse with ignoreCase:false first.
+                if (!Enum.TryParse(propertyName, ignoreCase: false, out TKey key) &&
+                    !Enum.TryParse(propertyName, ignoreCase: true, out key)) {
+                    throw new JsonException(
+                        $"Unable to convert \"{propertyName}\" to Enum \"{_keyType}\".");
+                }
+
+                // Get the value.
+                reader.Read();
+                TValue value = _valueConverter.Read(ref reader, _valueType, options)!;
+
+                // Add to dictionary.
+                dictionary.Add(key, value);
+            }
+
+            throw new JsonException();
+        }
+
+        public override void Write(
+            Utf8JsonWriter writer,
+            Dictionary<TKey, TValue> dictionary,
+            JsonSerializerOptions options) {
+            writer.WriteStartObject();
+
+            foreach ((TKey key, TValue value) in dictionary) {
+                string propertyName = key.ToString();
+                writer.WritePropertyName
+                    (options.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName);
+
+                _valueConverter.Write(writer, value, options);
+            }
+
+            writer.WriteEndObject();
+        }
+    }
+}*/
\ No newline at end of file