pub struct Envelope { /* private fields */ }Expand description
A complete weir wire frame: validated header + payload bytes.
Fields are private and read-only (header /
payload). Envelope::new makes the payload
authoritative for header.payload_len, so the declared length and the
actual payload can never disagree.
Implementations§
Source§impl Envelope
impl Envelope
Sourcepub fn new(header: Header, payload: impl Into<Payload>) -> Self
pub fn new(header: Header, payload: impl Into<Payload>) -> Self
Builds a frame from a header and payload. The header’s payload_len is
overwritten with the payload’s actual length, so the two cannot desync
— the payload is the single source of truth for the length on the wire.
Sourcepub fn encode(&self) -> Vec<u8> ⓘ
pub fn encode(&self) -> Vec<u8> ⓘ
Serialises the full frame: header bytes + payload bytes + payload CRC32 (LE).
Sourcepub fn decode(buf: &[u8]) -> Result<Self, DecodeError>
pub fn decode(buf: &[u8]) -> Result<Self, DecodeError>
Decodes and validates a complete frame from a byte slice.
Validation order defends against pre-allocation DoS:
- Buffer length >= HEADER_LEN — check before any parsing.
- Header decode (magic → version → CRC) — before touching payload.
payload_len <= MAX_PAYLOAD_HARD_CAP— rejection before any heap allocation.- Buffer length == HEADER_LEN + payload_len + 4 — the buffer must be
exactly one frame: shorter is
TruncatedFrame, longer isTrailingBytes(the caller owns framing; the codec never silently discards a remainder — G18). - Payload CRC — validate after allocation, before returning data to caller.
The socket layer applies an additional cap (min(config.max_payload_bytes, MAX_PAYLOAD_HARD_CAP))
before reaching this function. This function applies only the hard cap as a safety floor.