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§
Sourcetype Error: From<ErrorKind>
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§
Sourcefn encode(&self, writer: &mut impl Write) -> Result<usize, Self::Error>
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§
Sourcefn encoded_size(&self) -> Result<usize, Self::Error>
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).
Sourcefn encode_to_slice(
&self,
buf: &mut [u8],
) -> Result<usize, EncodeToSliceError<Self::Error>>
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".