using System.Runtime.CompilerServices; using AyCode.Core.Serializers.Binaries; using AyCode.Core.Tests.TestModels; namespace AyCode.Core.Tests.GeneratedWriters; /// /// Hand-written generated binary writer for TestOrder_All_True. /// Demonstrates the pattern that the source generator will produce. /// /// Bypasses the runtime switch/delegate property loop: /// - Direct obj.Property access instead of Func<>.Invoke() /// - No switch dispatch per property /// - No boxing for value types /// - Small method (~500B native) vs 27KB WriteObject — better ICache /// /// Properties are written in alphabetical order to match the runtime serializer. /// Complex/Collection properties fall back to the runtime serializer via WriteValue. /// internal sealed class TestOrderWriter : IGeneratedBinaryWriter { internal static readonly TestOrderWriter Instance = new(); public void WriteProperties(object value, AcBinarySerializer.BinarySerializationContext context) where TOutput : struct, IBinaryOutputBase { var obj = Unsafe.As(value); // Properties in alphabetical order (matching runtime serializer): // AuditMetadata: MetadataInfo_All_True? (complex, nullable) WriteComplexOrNull(obj.AuditMetadata, context); // Category: SharedCategory_All_True? (complex, nullable) WriteComplexOrNull(obj.Category, context); // CreatedAt: DateTime (markerless) context.WriteDateTimeBits(obj.CreatedAt); // Id: int (markerless) context.WriteVarInt(obj.Id); // Items: List (collection) WriteComplexOrNull(obj.Items, context); // MetadataList: List (collection) WriteComplexOrNull(obj.MetadataList, context); // NoMergeItems: List (collection) WriteComplexOrNull(obj.NoMergeItems, context); // OrderMetadata: MetadataInfo_All_True? (complex, nullable) WriteComplexOrNull(obj.OrderMetadata, context); // OrderNumber: string AcBinarySerializer.WriteStringGenerated(obj.OrderNumber, context); // Owner: SharedUser? (complex, nullable) WriteComplexOrNull(obj.Owner, context); // PaidDateUtc: DateTime? (nullable) var paidDate = obj.PaidDateUtc; if (paidDate.HasValue) { context.WriteByte(BinaryTypeCode.DateTime); context.WriteDateTimeBits(paidDate.Value); } else { context.WriteByte(BinaryTypeCode.Null); } // PrimaryTag: SharedTag_All_True? (complex, nullable) WriteComplexOrNull(obj.PrimaryTag, context); // SecondaryTag: SharedTag_All_True? (complex, nullable) WriteComplexOrNull(obj.SecondaryTag, context); // Status: TestStatus (enum, markerless) context.WriteVarInt((int)obj.Status); // Tags: List (collection) WriteComplexOrNull(obj.Tags, context); // TotalAmount: decimal (markerless) context.WriteDecimalBits(obj.TotalAmount); } public void ScanObject(object value, AcBinarySerializer.BinarySerializationContext context) where TOutput : struct, IBinaryOutputBase { throw new NotImplementedException(); } public void ScanForDuplicates(object value, AcBinarySerializer.BinarySerializationContext context) where TOutput : struct, IBinaryOutputBase { if (!context.HasCaching) return; ScanObject(value, context); context.SortWritePlan(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteComplexOrNull(object? value, AcBinarySerializer.BinarySerializationContext context) where TOutput : struct, IBinaryOutputBase { if (value == null) { context.WriteByte(BinaryTypeCode.PropertySkip); return; } AcBinarySerializer.WriteValueGenerated(value, value.GetType(), context); } }