pub trait DynCodec:
Send
+ Sync
+ Debug {
// Required methods
fn create_deserializer<'a>(
&self,
input: &'a [u8],
) -> Box<dyn ShapeDeserializer + 'a>;
fn create_serializer(&self) -> Box<dyn PayloadSerializer + '_>;
}Expand description
Object-safe sibling of Codec exposing dynamic deserializer creation.
§Why a sibling trait?
Codec uses associated types (Serializer, Deserializer<'a>) and
returns them by value from its methods. This gives codec consumers
zero-cost static dispatch — the compiler can inline and monomorphize
serializer/deserializer creation at call sites that know the concrete
codec type. That is the right choice for the common case (generated code
that knows the protocol statically).
However, some features require accessing a codec through a trait object.
The SEP-specified ClientProtocol::payload_codec() method returns “the
codec” in a context where the ClientProtocol itself is accessed via
dyn ClientProtocol (see SharedClientProtocol,
which stores Arc<dyn ClientProtocol> for runtime protocol swapping).
Returning a Codec through dyn is not possible in Rust because
associated types and by-value returns are not object-safe.
DynCodec is the minimal object-safe view that covers the operations
needed through a trait object. It exists purely as a Rust adaptation of
the SEP’s object-oriented Codec design; it is not additional user-facing
API. A blanket impl<C: Codec> DynCodec for C makes every concrete codec
automatically usable through &dyn DynCodec without any extra work from
codec authors.
Both deserializer and serializer creation are exposed through this trait
to support event-stream marshalling (input streams) and unmarshalling
(output streams) through dyn ClientProtocol.
§Returning (de)serializers as boxed trait objects
ShapeDeserializer implementations typically hold cursor state over an
input byte slice (e.g., JsonDeserializer holds input: &'a [u8] and a
position: usize). Producing a fresh deserializer positioned at the start
of the input is the standard way to read independent messages — as is
required for event-stream frames, where each frame is an independent
serialized payload. The returned Box<dyn ShapeDeserializer + 'a>
borrows from input, so the caller retains ownership of the bytes for
the duration of deserialization. Similarly each event frame requires a
fresh serializer.
Required Methods§
Sourcefn create_deserializer<'a>(
&self,
input: &'a [u8],
) -> Box<dyn ShapeDeserializer + 'a>
fn create_deserializer<'a>( &self, input: &'a [u8], ) -> Box<dyn ShapeDeserializer + 'a>
Creates a new deserializer over the given input bytes.
Sourcefn create_serializer(&self) -> Box<dyn PayloadSerializer + '_>
fn create_serializer(&self) -> Box<dyn PayloadSerializer + '_>
Creates a new serializer. Use PayloadSerializer::finish_boxed to
consume the serializer and obtain the serialized bytes.