From a129b321998614b20e4ebb8a7c1632553ebee981 Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Sat, 1 Jun 2024 19:02:28 +0200 Subject: Split event abstractions --- .../Converters/EventConverterFactory.cs | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs (limited to 'LibMatrix.EventTypes.Abstractions/Converters/EventConverterFactory.cs') 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 : + JsonConverter> where TKey : struct, Enum { + private readonly JsonConverter _valueConverter; + private readonly Type _keyType; + private readonly Type _valueType; + + public DictionaryEnumConverterInner(JsonSerializerOptions options) { + // For performance, use the existing converter. + _valueConverter = (JsonConverter)options + .GetConverter(typeof(TValue)); + + // Cache the key and value types. + _keyType = typeof(TKey); + _valueType = typeof(TValue); + } + + public override Dictionary Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) { + if (reader.TokenType != JsonTokenType.StartObject) { + throw new JsonException(); + } + + var dictionary = new Dictionary(); + + 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 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 -- cgit 1.4.1