Expand description
Serialization families for Consortium IPC and TEE parameter conversion.
A Consortium link carries typed messages, but the wire carries bytes. This
crate is the seam: Codec names a serialization family, CodecFor<T>
says that family can handle a particular message type, and everything above —
consortium_ipc::Channel, consortium_tee::TeeParam — is generic over it.
§Architecture
The trait pair is split so that a family’s error type is declared once:
Codec one impl per family; declares Error
└── CodecFor<T> one impl per (family, message type); encode/decodeThe load-bearing detail is that CodecFor::Decoded is an associated type
constructor, not T:
| Codec | Decoded<'buf> | Cost of a recv |
|---|---|---|
PostcardCodec | T | deserializes into an owned value |
ProstCodec | T | deserializes into an owned value |
RkyvCodec | &'buf T::Archived | validates and borrows the buffer |
Callers must therefore not assume decode produces an owned T.
consortium_ipc::ReceivedMessage wraps Decoded<'buf> and Derefs to T
where the codec allows it, so call sites written against it survive a codec
swap unchanged.
Encoding is always into a caller-supplied &mut [u8] and returns the byte
count. There is no allocation in the trait signature, which is what lets the
same codec serve a no_std firmware channel and a Linux one.
§Features
no_std by default, and there is no default codec — a consumer names the
family it wants, so firmware does not pay for one it never calls.
| Feature | Exposes |
|---|---|
postcard | PostcardCodec (serde, compact, owned decode) |
prost | ProstCodec (protobuf, owned decode) |
rkyv | RkyvCodec, TrustedArchive (zero-copy) |
alloc | heap-backed paths, including validated rkyv |
std | alloc plus tracing-routed diagnostics |
defmt | routes the same diagnostics to defmt |
§Example
use consortium_codec::{CodecFor, PostcardCodec};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Telemetry { sequence: u32, ready: bool }
let mut buf = [0u8; 32];
let n = PostcardCodec::encode(&Telemetry { sequence: 7, ready: true }, &mut buf)?;
let back: Telemetry = <PostcardCodec as CodecFor<Telemetry>>::decode(&buf[..n])?;§Implementing a codec
Add a unit struct, impl Codec for it to declare Error, then
impl<T> CodecFor<T> for MyCodec where T: <your serialization bound>. Set
Decoded<'buf> to T for an owning codec or to a borrow of 'buf for a
zero-copy one. Encode must report the exact byte count written and must fail
rather than truncate when buf is too small — a transport sends buf[..n]
verbatim.