pub struct TaggedSerializeProduct<'ser, 'a, W: Write> {
product: Product,
parent: &'ser mut Serializer<'a, W>,
next_position: usize,
strategy: EncodingStrategy,
buffer: bool,
entries: Vec<(u8, Vec<u8>)>,
}Expand description
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 each
serialize_field call appends a (tag, value) pair to the writer
through the parent Serializer, so any nested tagged
value in value recurses through the wrapper instead of falling through
to rmp_serde’s default positional-array struct encoding.
next_position is only consulted by the SerializeTupleStruct impl;
the SerializeStruct impl ignores it.
strategy drives the per-field emission: under Tagged each entry is
(tag, value) on the wire, under Array each entry is just value.
Behavior splits on the buffer flag, decided at begin_product time:
buffer = false(the common path): the outer header is written upfront and eachserialize_fieldwrites through the parent stream immediately. Used when reordering can’t change the wire (Taggedwith any source order, orArraywhose source order is already tag-ascending). Theentriesfield stays empty.buffer = true: the outer header is deferred andserialize_fieldencodes the value into a freshVec<u8>through a sub-serializer that shares the parent’s registry + strategy, then pushes(tag, bytes)toentries. Thefinishflush atend()sorts by tag and dumps in canonical order to the parent. Only reached forArray-strategy types whose source-declaration order doesn’t match tag-ascending order.
Fields§
§product: Product§parent: &'ser mut Serializer<'a, W>§next_position: usize§strategy: EncodingStrategy§buffer: bool§entries: Vec<(u8, Vec<u8>)>Implementations§
Source§impl<'ser, 'a, W: Write> TaggedSerializeProduct<'ser, 'a, W>
impl<'ser, 'a, W: Write> TaggedSerializeProduct<'ser, 'a, W>
Sourcefn serialize_tag_and_value<T>(
&mut self,
tag: u8,
value: &T,
) -> Result<(), Error>
fn serialize_tag_and_value<T>( &mut self, tag: u8, value: &T, ) -> Result<(), Error>
Emit one field’s wire contribution. Direct path (the common case):
write (tag, value) under Tagged or just value under Array,
straight to the parent stream. Buffered path (Array with
non-monotonic source order): encode the value into a temp
Vec<u8> through a sub-serializer that shares the parent’s
registry + strategy and push (tag, bytes) to entries for
later flushing in finish. Either path keeps nested tagged
types recursing through the wrapper.
Sourcefn finish(self) -> Result<(), Error>
fn finish(self) -> Result<(), Error>
Flush the deferred state: under the direct path the header and
every value have already been written, so this is a no-op. Under
the buffered path, sort entries by tag, write the strategy-
appropriate header, then emit each (tag-prefix?, value-bytes)
pair to the parent.
Trait Implementations§
Source§impl<'ser, 'a, W: Write> SerializeStruct for TaggedSerializeProduct<'ser, 'a, W>
Named-field struct (struct Foo { a: u32, b: bool }). Each
serialize_field(name, value) call resolves name against the
registered Product (honoring #[serde(rename)]) to derive the wire
tag, then writes tag and value through the parent.
impl<'ser, 'a, W: Write> SerializeStruct for TaggedSerializeProduct<'ser, 'a, W>
Named-field struct (struct Foo { a: u32, b: bool }). Each
serialize_field(name, value) call resolves name against the
registered Product (honoring #[serde(rename)]) to derive the wire
tag, then writes tag and value through the parent.
Source§impl<'ser, 'a, W: Write> SerializeStructVariant for TaggedSerializeProduct<'ser, 'a, W>
Struct variant payload (enum E { ... Named { a: u32, b: bool } }). Same
payload shape and tag-resolution rule as a top-level named struct.
impl<'ser, 'a, W: Write> SerializeStructVariant for TaggedSerializeProduct<'ser, 'a, W>
Struct variant payload (enum E { ... Named { a: u32, b: bool } }). Same
payload shape and tag-resolution rule as a top-level named struct.
Source§impl<'ser, 'a, W: Write> SerializeTupleStruct for TaggedSerializeProduct<'ser, 'a, W>
Multi-element tuple struct (struct Pair(u32, bool)). serde calls
serialize_field(value) once per element in source-declaration order
without supplying a name, so we keep an internal position counter and
look up the wire tag for the source position (the registered Product
uses positional names "0", "1", … as wire-name strings). Resolving by
position lets #[tag(N)]-reordered tuple structs (e.g.
struct Triple(#[tag(2)] u32, #[tag(0)] bool, #[tag(1)] u8)) emit each
field under the right wire tag even though the calls arrive in source
order — and the buffer-and-flush in finish then writes them on the
wire in tag-ascending order.
impl<'ser, 'a, W: Write> SerializeTupleStruct for TaggedSerializeProduct<'ser, 'a, W>
Multi-element tuple struct (struct Pair(u32, bool)). serde calls
serialize_field(value) once per element in source-declaration order
without supplying a name, so we keep an internal position counter and
look up the wire tag for the source position (the registered Product
uses positional names "0", "1", … as wire-name strings). Resolving by
position lets #[tag(N)]-reordered tuple structs (e.g.
struct Triple(#[tag(2)] u32, #[tag(0)] bool, #[tag(1)] u8)) emit each
field under the right wire tag even though the calls arrive in source
order — and the buffer-and-flush in finish then writes them on the
wire in tag-ascending order.
Source§impl<'ser, 'a, W: Write> SerializeTupleVariant for TaggedSerializeProduct<'ser, 'a, W>
Tuple variant payload (enum E { ... Pair(u32, bool) }). Same payload
shape and tag-resolution rule as a top-level tuple struct — the variant’s
payload Product uses positional names ("0", "1", …). The outer
{variant_tag: ...} map (1-entry discriminator) was written upfront in
serialize_tuple_variant; the payload’s header is deferred to
finish() along with every other product’s.
impl<'ser, 'a, W: Write> SerializeTupleVariant for TaggedSerializeProduct<'ser, 'a, W>
Tuple variant payload (enum E { ... Pair(u32, bool) }). Same payload
shape and tag-resolution rule as a top-level tuple struct — the variant’s
payload Product uses positional names ("0", "1", …). The outer
{variant_tag: ...} map (1-entry discriminator) was written upfront in
serialize_tuple_variant; the payload’s header is deferred to
finish() along with every other product’s.