using System.ComponentModel; using Newtonsoft.Json; using Pf2eModel; using Pf2eModel.Model; using Pf2eModel.Model.Base; using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Structure; namespace Pf2eViewer.Converters; internal class EntityConverter : JsonConverter { private readonly Pf2eDbContext _context = new(); public override bool CanConvert(Type objectType) { return objectType == typeof(Entity) || objectType.IsAssignableTo(typeof(IEntity)); } private Dictionary DictionarySerialization(object source) { Dictionary dictionary = []; foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source)) { if (property.Attributes.OfType().Any()) { continue; } object? v = property.GetValue(source); dictionary.Add(property.Name, v); } return dictionary; } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (value == null) { serializer.Serialize(writer, null); return; } Dictionary dictionary = DictionarySerialization(value); if (value.GetType() != typeof(Entity)) { dictionary.Remove("Entity"); Processor? processor = _processors.FirstOrDefault(p => p.Type == value.GetType()); processor?.Process(dictionary, (IEntity)value, this); } else { dictionary.Remove("Description"); } serializer.Serialize(writer, dictionary); } private abstract class Processor { public abstract Type Type { get; } public abstract void Process( Dictionary dictionary, IEntity entity, EntityConverter converter ); } private class Processor(Action, T, EntityConverter> method) : Processor where T : IEntity { public override Type Type { get; } = typeof(T); public override void Process( Dictionary dictionary, IEntity entity, EntityConverter converter ) { method.Invoke(dictionary, (T)entity, converter); } } private readonly ICollection _processors = [ new Processor( (dictionary, trait, converter) => { LocaleString name = // ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract trait.Entity?.Name ?? converter ._context.Entities.Where(e => e.Id == trait.Id) .Select(e => e.Name) .FirstOrDefault()!; dictionary.Remove("Entity"); dictionary.Remove("Entities"); dictionary.Add("Name", name.ToString()); } ), new Processor( (dictionary, _, _) => { dictionary.Remove("Group"); } ), ]; public override bool CanRead => false; public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer ) { throw new NotImplementedException( "Unnecessary because CanRead is false. The type will skip the converter." ); } }