Skip to main content

Encode

Trait Encode 

Source
pub trait Encode {
    type Error: From<ErrorKind>;

    // Required method
    fn encode(&self, writer: &mut impl Write) -> Result<usize, Self::Error>;

    // Provided methods
    fn encoded_size(&self) -> Result<usize, Self::Error> { ... }
    fn encode_to_slice(
        &self,
        buf: &mut [u8],
    ) -> Result<usize, EncodeToSliceError<Self::Error>> { ... }
}
Expand description

TX-side: serialize self into an embedded_io::Write sink.

Required Associated Types§

Source

type Error: From<ErrorKind>

Per-implementation error; constructible from an I/O embedded_io::ErrorKind so the fixed-width write_* leaf helpers lift through ?.

The variable-width helper write_be_uint returns WriteUintError instead; to call it inside encode with ?, additionally implement From<WriteUintError> for your error (match both arms — see the error pattern in MIGRATION.md).

Required Methods§

Source

fn encode(&self, writer: &mut impl Write) -> Result<usize, Self::Error>

Serialize into writer; return the number of bytes written.

encode must be a pure function of &self — same bytes every call, no observable side effects. The trait’s provided methods may invoke it more than once per logical serialization: the default encoded_size counts by encoding into a CountingSink, and encode_to_slice re-runs sizing after a failed encode to classify the error. An implementation that mutates through interior mutability (e.g. a rolling sequence or alive counter advanced inside encode) will have that side effect applied per invocation, not per frame — advance such state outside encode, then encode the snapshot.

§Errors

Self::Error if the sink rejects a write or the value cannot be encoded.

Provided Methods§

Source

fn encoded_size(&self) -> Result<usize, Self::Error>

Exact number of bytes encode will write.

The default runs encode against an infallible CountingSink (one extra encode invocation per size query — see the purity requirement on encode) and returns the bytes actually written — correct by construction, so hand-maintained sizes cannot drift from encode (the bug class every migrated consumer had). Override only where a closed-form size is cheaper on a hot path; an override MUST return exactly the byte count a successful encode writes — nested encoders reserve space from it with no staging buffer. Because the default runs a full encode pass, call sites that size before encoding (nested length-prefix encoders, which compound per level) traverse the value once per size query under the default, so hot paths should prefer closed-form overrides.

An encode implementation that relies on this default must NOT call self.encoded_size() (infinite recursion). Calling encoded_size() on nested fields is fine, and is the intended pre-sizing pattern.

§Errors

Whatever encode returns for a value that cannot be encoded; the counting sink itself never fails.

§Panics

In debug builds, if encode returns a byte count different from the bytes it actually wrote — that is a bug in the encode impl (written == encoded_size()? is a hard invariant).

Source

fn encode_to_slice( &self, buf: &mut [u8], ) -> Result<usize, EncodeToSliceError<Self::Error>>

Encode into a fixed slice, reporting needed/available (InsufficientBuffer) instead of a bare embedded_io::ErrorKind::WriteZero when the slice is too small, and hiding the &mut &mut [u8] cursor re-borrow every fixed-buffer call site otherwise writes by hand.

The success path is a single encode pass — encoded_size is consulted only after a failed encode, to classify the error (under the default encoded_size that means a second encode invocation; see the purity requirement on encode). On error, buf may hold partially written bytes; on success, bytes past the returned count are untouched.

§Errors

EncodeToSliceError::InsufficientBuffer if buf is smaller than encoded_size(); EncodeToSliceError::Encode if encoding itself fails.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§