CultLib/tests/GameCult.Caching.Tests/AssemblyInfo.cs
Meta Vens ea5a07b37a Own serialization options by the document's assembly
The static UntrustedData options are gone. An assembly declares its formatter
resolvers with [assembly: CultCacheFormatterResolver(typeof(R))];
CultDocumentMessagePackSerialization.OptionsFor(assembly) composes them ahead
of CultDocumentResolver and StandardResolver, once per assembly, and hands
assemblies that declare nothing the base Options. Generated codecs and the
reflective SerializeUntyped/DeserializeUntyped path both read
OptionsFor(typeof(X).Assembly). No registration call, no mutable options, no
load order.

CultMessagePackSecurity copies UntrustedData and supplies a collision-resistant
comparer over CultRecordRef<T>.Key.Value, so ref-keyed dictionaries
deserialize.

Tests: RefKeyedDictionaryRoundTrips failed on 825b4f7 ("No hash-resistant
equality comparer available"); DeclaredResolverEncodesValueTypeAsPositionalArray
and UnknownAssemblyGetsBaseOptions did not compile there (new API);
InteropNoteBytesUnchanged is a pin whose payload constant was captured on
825b4f7. BenchItem, the one unkeyed [CultDocument] in any consumer (in-memory
benchmark, no store), gains [Key]s in its existing slot order.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 21:12:53 +02:00

43 lines
1.4 KiB
C#

using GameCult.Caching.MessagePack;
using GameCult.Caching.Tests;
using MessagePack;
using MessagePack.Formatters;
[assembly: CultCacheFormatterResolver(typeof(PairResolver))]
namespace GameCult.Caching.Tests
{
public struct Pair
{
public float A;
public float B;
}
public sealed class PairResolver : IFormatterResolver
{
public static readonly IFormatterResolver Instance = new PairResolver();
public IMessagePackFormatter<T>? GetFormatter<T>()
{
return typeof(T) == typeof(Pair) ? (IMessagePackFormatter<T>)(object)PairFormatter.Instance : null;
}
private sealed class PairFormatter : IMessagePackFormatter<Pair>
{
public static readonly PairFormatter Instance = new();
public void Serialize(ref MessagePackWriter writer, Pair value, MessagePackSerializerOptions options)
{
writer.WriteArrayHeader(2);
writer.Write(value.A);
writer.Write(value.B);
}
public Pair Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
if (reader.ReadArrayHeader() != 2) throw new MessagePackSerializationException("Pair is a two-element array.");
return new Pair { A = reader.ReadSingle(), B = reader.ReadSingle() };
}
}
}
}