115 lines
4.0 KiB
C#
115 lines
4.0 KiB
C#
using System.Runtime.CompilerServices;
|
|
using AyCode.Core.Serializers.Binaries;
|
|
using AyCode.Core.Tests.TestModels;
|
|
|
|
namespace AyCode.Core.Tests.GeneratedWriters;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
internal sealed class TestOrderWriter : IGeneratedBinaryWriter
|
|
{
|
|
internal static readonly TestOrderWriter Instance = new();
|
|
|
|
public void WriteProperties<TOutput>(object value,
|
|
AcBinarySerializer.BinarySerializationContext<TOutput> context)
|
|
where TOutput : struct, IBinaryOutputBase
|
|
{
|
|
var obj = Unsafe.As<TestOrder_All_True>(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<TestOrderItem_All_True> (collection)
|
|
WriteComplexOrNull(obj.Items, context);
|
|
|
|
// MetadataList: List<MetadataInfo_All_True> (collection)
|
|
WriteComplexOrNull(obj.MetadataList, context);
|
|
|
|
// NoMergeItems: List<TestOrderItem_All_True> (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<SharedTag_All_True> (collection)
|
|
WriteComplexOrNull(obj.Tags, context);
|
|
|
|
// TotalAmount: decimal (markerless)
|
|
context.WriteDecimalBits(obj.TotalAmount);
|
|
}
|
|
|
|
public void ScanObject<TOutput>(object value, AcBinarySerializer.BinarySerializationContext<TOutput> context) where TOutput : struct, IBinaryOutputBase
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void ScanForDuplicates<TOutput>(object value, AcBinarySerializer.BinarySerializationContext<TOutput> context) where TOutput : struct, IBinaryOutputBase
|
|
{
|
|
if (!context.HasCaching) return;
|
|
ScanObject(value, context);
|
|
context.SortWritePlan();
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static void WriteComplexOrNull<TOutput>(object? value, AcBinarySerializer.BinarySerializationContext<TOutput> context)
|
|
where TOutput : struct, IBinaryOutputBase
|
|
{
|
|
if (value == null)
|
|
{
|
|
context.WriteByte(BinaryTypeCode.PropertySkip);
|
|
return;
|
|
}
|
|
|
|
AcBinarySerializer.WriteValueGenerated(value, value.GetType(), context);
|
|
}
|
|
}
|