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+)

TierEntryBad buffer
Checkedtry_wrap / try_wrap_and_apply_header / try_decodeResult::Err (all failures)
Trustedbare wrap / wrap_and_apply_headerpanic after the same extent proof
Trusted hybridbare decodepanic if short; Err on wrong template/schema only
Uncheckedunsafe wrap_unchecked / wrap_and_apply_header_uncheckedUB — prove extent first
Unchecked hybridunsafe decode_uncheckedUB 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).