Trust Boundaries
Checked entry points validate the message header and fixed block. verify
walks the complete dynamic tail before bulk access:
#![allow(unused)] fn main() { pub fn demo_try_vs_trusted(valid_car: &[u8]) -> Result<(), Box<dyn std::error::Error>> { // `decode` validates template_id, schema_id, version, and the // version-aware fixed body extent at message start (offset 0). let _dec = CarDecoder::try_decode(valid_car, 0)?; // `verify` walks the complete dynamic tail (groups + var-data), not a // header-only peek — use it when you need full structural acceptance // without materialising a long-lived decoder stage chain. CarDecoder::verify(valid_car)?; // Truncated buffers fail checked entry points with Result errors. assert!( CarDecoder::try_decode(&valid_car[..8.min(valid_car.len())], 0).is_err(), "truncated buffer should fail try_decode" ); if valid_car.len() > 16 { assert!( CarDecoder::verify(&valid_car[..16]).is_err(), "truncated buffer should fail verify (incomplete tail)" ); } // `wrap` still returns Result and validates the body extent given acting // block_length + version (message start, not sbe-tool body offset). let mut hdr_bytes = [0u8; 8]; hdr_bytes.copy_from_slice(&valid_car[..8]); let hdr = MessageHeader(hdr_bytes); let dec = CarDecoder::try_wrap(valid_car, 0, hdr.block_length() as usize, hdr.version())?; assert_eq!(dec.serial_number(), 1234); Ok(()) } }
(This code comes from the sbe-feature-tour sample crate.)
Three-tier constructors (0.1.12+)
| Tier | Entry | Bad buffer |
|---|---|---|
| Checked | try_wrap / try_wrap_and_apply_header / try_decode | Result::Err (all failures) |
| Trusted | bare wrap / wrap_and_apply_header | panic after the same extent proof |
| Trusted hybrid | bare decode | panic if short; Err on wrong template/schema only |
| Unchecked | unsafe wrap_unchecked / wrap_and_apply_header_unchecked | UB — prove extent first |
| Unchecked hybrid | unsafe decode_unchecked | UB on OOB extent; Err on wrong template/schema |
Bare decode looks like try_decode (Result) but short buffers still panic
— prefer try_decode when every failure must be a Result. Full table:
Trust Boundary (core concepts). sbe-tool
offsets: Coming from sbe-tool.
Trust boundary
The constructor is the single trust checkpoint. After a safe constructor
proves header + version-aware fixed extent, field accessors and setters are
branch-free (unchecked loads/stores justified by that proof). Dynamic
group/var-data tails still check on consume. Use *_unchecked only when you
have proven the fixed extent independently (benchmarks, pre-validated buffers).