using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; using ExpenseTracker.Domain.Entities; using ExpenseTracker.Domain.Enums; namespace ExpenseTracker.Persistence.Serializers; public class TransactionSerializer : SerializerBase, IBsonDocumentSerializer { private const string IdDeserializedFieldName = "Id"; private const string IdSerializedFieldName = "_id"; private const string AmountDeserializedFieldName = "Amount"; private const string AmountSerializedFieldName = "amount"; private const string CategoryDeserializedFieldName = "Category"; private const string CategorySerializedFieldName = "category"; private const string TimeDeserializedFieldName = "Time"; private const string TimeSerializedFieldName = "time"; private const string DescriptionDeserializedFieldName = "Description"; private const string DescriptionSerializedFieldName = "description"; private const string AccountIdDeserializedFieldName = "AccountId"; private const string AccountIdSerializedFieldName = "accountId"; public override Transaction Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { context.Reader.ReadStartDocument(); var entity = new Transaction(); while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) { var fieldName = context.Reader.ReadName(); switch (fieldName) { case IdSerializedFieldName: entity.Id = context.Reader.ReadString(); break; case AmountSerializedFieldName: entity.Amount = context.Reader.ReadDouble(); break; case CategorySerializedFieldName: entity.Category = Category.FromName(context.Reader.ReadString()); break; case TimeSerializedFieldName: entity.Time = DateTimeOffset.FromUnixTimeMilliseconds(context.Reader.ReadDateTime()); break; case DescriptionSerializedFieldName: var description = context.Reader.ReadString(); entity.Description = description.Equals(String.Empty) ? null : description; break; case AccountIdSerializedFieldName: entity.AccountId = context.Reader.ReadString(); break; } } context.Reader.ReadEndDocument(); return entity; } public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Transaction value) { context.Writer.WriteStartDocument(); context.Writer.WriteString(IdSerializedFieldName, value.Id); context.Writer.WriteDouble(AmountSerializedFieldName, value.Amount); context.Writer.WriteString(CategorySerializedFieldName, value.Category.Name); context.Writer.WriteDateTime(TimeSerializedFieldName, value.Time.ToUnixTimeMilliseconds()); context.Writer.WriteString(DescriptionSerializedFieldName, value.Description ?? String.Empty); context.Writer.WriteString(AccountIdSerializedFieldName, value.AccountId); context.Writer.WriteEndDocument(); } public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo) { switch (memberName) { case IdDeserializedFieldName: serializationInfo = new BsonSerializationInfo(IdSerializedFieldName, new StringSerializer(), typeof(string)); return true; case AmountDeserializedFieldName: serializationInfo = new BsonSerializationInfo(AmountSerializedFieldName, new DoubleSerializer(), typeof(double)); return true; case CategoryDeserializedFieldName: serializationInfo = new BsonSerializationInfo(CategorySerializedFieldName, new StringSerializer(), typeof(string)); return true; case TimeDeserializedFieldName: serializationInfo = new BsonSerializationInfo(TimeSerializedFieldName, new DateTimeSerializer(), typeof(DateTimeOffset)); return true; case DescriptionDeserializedFieldName: serializationInfo = new BsonSerializationInfo(DescriptionSerializedFieldName, new StringSerializer(), typeof(string)); return true; case AccountIdDeserializedFieldName: serializationInfo = new BsonSerializationInfo(AccountIdSerializedFieldName, new StringSerializer(), typeof(string)); return true; default: serializationInfo = null; return false; } } }