// Copyright Epic Games, Inc. All Rights Reserved. using System.Reflection; using EpicGames.Core; using EpicGames.Horde; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; using ProtoBuf; namespace HordeServer.Utilities { /// /// Class which serializes object id types to BSON /// public sealed class StringIdBsonSerializer : SerializerBase where TValue : struct where TConverter : StringIdConverter, new() { readonly TConverter _converter = new TConverter(); /// public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) => _converter.FromStringId(new StringId(new Utf8String(context.Reader.ReadString()), StringId.Validate.None)); /// public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value) => context.Writer.WriteString(_converter.ToStringId(value).ToString()); } /// /// Class which serializes object id types to BSON /// public sealed class StringIdBsonSerializationProvider : BsonSerializationProviderBase { /// public override IBsonSerializer? GetSerializer(Type type, IBsonSerializerRegistry serializerRegistry) { StringIdConverterAttribute? attribute = type.GetCustomAttribute(); if (attribute == null) { return null; } return (IBsonSerializer?)Activator.CreateInstance(typeof(StringIdBsonSerializer<,>).MakeGenericType(type, attribute.ConverterType)); } } #pragma warning disable CS1591 /// /// Surrogate type for serializing StringId types to ProtoBuf /// [ProtoContract] public struct StringIdProto where TValue : struct where TConverter : StringIdConverter, new() { static readonly TConverter s_converter = new TConverter(); [ProtoMember(1)] public string? Id { get; set; } public static implicit operator TValue(StringIdProto source) => s_converter.FromStringId(new StringId(source.Id!)); public static implicit operator StringIdProto(TValue source) => new StringIdProto { Id = s_converter.ToStringId(source).ToString() }; } #pragma warning restore CS1591 }