Expand description
Tagged-map msgpack serializer that wraps [rmp_serde::Serializer].
Most of serde::Serializer’s methods are forwarded to the inner
rmp_serde serializer unchanged — we only intercept the structurally
significant calls (serialize_struct, the variant methods, etc.) and
re-emit them as integer-keyed msgpack maps using the TagRegistry.
The public entry point is msgpack_tagged_serialize, which builds the
registry up front via T::register_into and runs the value through the
wrapper. The wrapper in turn writes to a Vec<u8> we hand back to the
caller.
Every aggregate shape is intercepted: named structs, multi-element tuple
structs, sequences, fixed-length tuples, free-form maps, and all four
variant kinds (unit / newtype / tuple / struct). Primitives, top-level
newtype structs, and Option forward through to inner — recursing into
nested values via this same wrapper so any tagged value reachable from
the root keeps the int-keyed-map treatment.
§Known gaps vs. the design doc / macro syntax
The wrapper isn’t final — the bits below are accepted by
#[derive(MsgpackTagged)] today but aren’t reflected in the wire bytes
we produce yet.
- Tag-ascending wire order. The design promises field/element entries on the wire in tag-ascending order so two semantically-equal values encode byte-identically regardless of source-declaration order. We currently emit in serde’s call-order = source-declaration order. Tightening this requires buffering field bytes before writing.
- Encoding strategies. Only the Tagged strategy (int-keyed map) is implemented. Per-type strategy overrides — Array (positional msgpack array, smallest wire) and Named (rmp_serde default, string-keyed map) — are deferred follow-ups.
assert_eq!onlenvsproduct.fields.len()— already tightened, but only inside the four product-shaped methods. New shapes that join the family should add the same assert.
Structs§
- Serializer
- Tagged-map msgpack serializer.
- Tagged
Serialize Product - Adapter for product shapes — both named structs and multi-element tuple
structs go through here. The two trait impls below differ only in how
they resolve a serde call to a wire tag: named-struct calls carry a
field-name string, tuple-struct calls carry an implicit position counter.
The map header is already written in the corresponding
serialize_*method before this adapter is constructed; from there eachserialize_fieldcall appends a(tag, value)pair to the writer through the parentSerializer, so any nested tagged value invaluerecurses through the wrapper instead of falling through tormp_serde’s default positional-array struct encoding. - Tagged
Serialize ViaParent - Stateless pass-through adapter shared by every shape whose only job is
to route element/key/value calls back through the parent
Serializer. The msgpack header (array length or map length) is written upfront in the correspondingserialize_*method before the adapter is constructed; from there each entry is just one or two more values appended to the writer through the wrapper, so any tagged value nested inside still gets the int-keyed-map treatment.
Functions§
- assert_
field_ 🔒count_ matches - Assert that serde’s reported field count matches the registered
Product’s — both should drop the same skipped fields, so they should always agree. A mismatch is a real misconfiguration: the most common cause is aPhantomData<T>field that’s missing#[serde(skip)], which would otherwise fail later with a confusing “field not found in registered Product” error from a tag lookup. The assert surfaces it earlier, with a more actionable message. - begin_
product_ 🔒payload - Decide whether to buffer + flush in tag-ascending order, write the
outer header upfront in the direct case, and return the configured
adapter. Shared by
Serializer::begin_product(top-level) andSerializer::begin_variant_payload(enum payload). - downgrade_
array_ 🔒if_ unsafe - Auto-downgrade
Array→Taggedfor products where the positional shape can’t safely round-trip the type’s own writes. - make_
inner_ 🔒rmp_ serializer - Build the inner
rmp_serde::Serializerfor primitive / forwarded calls. Single construction point so every spawn site (Serializer::new,Serializer::sub_serializer_into) stays in lockstep. - msgpack_
tagged_ serialize - Build the tag registry from
T::register_into, then serializevaluethrough aSerializerinto a freshly-allocatedVec<u8>. Uses the defaultEncodingStrategy::Taggedfor all types. For strategy customization, build the registry and serializer directly and use the builder methods. - write_
array_ 🔒header - Write a msgpack array header (
fixarray/array16/array32depending onlen) directly to the underlying writer. Used by sequences and tuples. - write_
map_ 🔒header - Write a msgpack map header (
fixmap/map16/map32depending onlen) directly to the underlying writer. Used by structs, maps, and the variant shapes once those land. - write_
strategy_ 🔒header - Write the outer Product header in the shape required by
strategy:Tagged→ int-keyedfixmap,Array→ positionalfixarray. Used by both top-level struct paths and variant-payload paths.
Type Aliases§
- RmpError 🔒
rmp_serde’s error type, re-exported for ourserde::Serializerimpl.