Feature Matrix
Scannable map of capabilities. Use the More links for samples and tests.
| Feature | What it does | How to use / more |
|---|---|---|
build.rs codegen | Compile-time schema → Rust module in OUT_DIR | generate_to_out_dir("schemas/….xml", config)? · plain include! or sbe_mod!(name) · Quick start · codegen examples |
| Wire compatibility | Same on-wire layout as official SBE | Dual encode ergo vs sbe-tool · sbe_tool_wire_parity_test · golden fixtures · Benchmarks · baseline_test |
| Flyweight decode | Zero-copy over &[u8] | CarDecoder::try_from(buf)?; car.serial_number() · feature-tour |
| Composite wire image | #[repr(transparent)] Engine([u8; N]) + LE accessors; flyweight default | Not a repr(C) overlay · Core ideas · composite_layout_test |
| Per-field vs whole struct | Flyweight or *FixedFields / *Domain | Single field: flyweight · always fill fixed block: .fixed(&CarFixedFields { … }) · whole message owned: CarDomain · Core ideas · feature-tour |
| Stage-struct encode + closures | Wire order as named monomorphic stages; groups via nested closures | bids(n, |g| g.add(|e| …))? · wrong order = missing method · Core ideas · Recipes · Benchmarks |
| Consuming decode stages | Distinct after-stage decoder types | into_bids(|lvl| …)? → into_asks(…)? → var-data · l3_consuming_stages_test |
| Decoder lanes | Random-access getters, staged into_*/skip_*, ordered callbacks, .memoized() | Any-order &Decoder, wire-order walk, or one callback per tail · decode stages |
| Staged group shape | Entries with their own tails take a visit closure returning the entry’s completion; fixed-stride entries yield an iterator | One pass either way — the completion is the next cursor, and fixed stride needs no measuring · Iterator only for &mut Iter, so for e in iter cannot drop the message tail · decode stages · l3_consuming_stages_test |
Ordered lane (decoder.ordered()) | Callbacks in wire order at message and nested-entry level as sbe_rt::Ordered<S>; EntryInfo { index, count, block_length } per entry | Façade over the staged stages — same single traversal, same compile-time tail order · message fixed takes a fixed-fields-only view · callbacks return DecodeError · nested ordered() returns the parent completion directly · message chain ends on encoded_length_with_header() · decode stages · ordered_lane_test |
| Non-advancing counts and lengths | <group>_count() / <field>_len() return Result<usize, DecodeError> without consuming a stage | Base decoder, .memoized(), the immediately preceding stage, and group entries · 0 for absent versioned tails · iter.remaining_entries() returns usize · an existing primary getter suppresses the colliding convenience accessor (same yield for entry acting_* and ordered fixed) · decode stages |
| Three-tier constructors | try_* → Result; bare wrap panics if short; bare decode panics if short and Err on wrong template/schema; unsafe *_unchecked | CarDecoder::try_decode(buf, 0)? · CarDecoder::verify(buf)? · demo_try_vs_trusted · Trust boundary |
| Placement metadata | Buffer utils on get_metadata() so field names remaining / buffer / limit / message_offset stay natural (no _field rename) | dec.get_metadata().remaining() · schema field remaining → dec.remaining() · Generated code · reserved_name_clash_test |
| Exact buffer sizing | Schema-aware length for nested/ragged msgs — no hand-calculated sizes | compute_length_with_header() (fixed) · compute_length_with_header(…) (flat) · *EncodedLength (nested) · Core ideas · l3-book · encoded_length_api_test |
| Schema docs → rustdoc | XML descriptions become item docs | description="…" / <description> / <comment> / <!-- --> · schema_docs_provenance_test |
Display / Debug | Diagnostic print (not wire format) | println!("{car}"); · Display / Debug · demo_display_debug |
| NULL / MIN / MAX | Schema sentinels as consts | MODEL_YEAR_NULL · baseline_test |
| Version-aware fields | sinceVersion / acting version | Option or skip on older wire · baseline_test · multi_schema_versioning_test |
| Groups / nested groups | Repeating dimensions | bids(n, |g| g.add(…))? · l3-book · l3_orderbook_test |
| Bulk group encode / decode | bulk_add(&[Entry]) / bulk_add_domain(&[EntryDomain]) / bulk_decode() -> Vec<Entry> for eligible flat groups | DTO re-encode selects the domain bulk path automatically when wire and domain fields match; measure against per-entry add() for your schema · group_encode_bench |
| Var-data / text | Length-prefix; optional UTF-8/ASCII | manufacturer_as_str("Honda")? when a characterEncoding is declared, else manufacturer(b"Honda")? · feature-tour |
| Fixed arrays + bulk helpers | Arrays, put, pad string, copy-out | put_some_numbers(…) · vehicle_code_str · copy_vehicle_code · java_parity_features_test |
| Enums / sets / bool | Wire enums, bitsets, _bool | available() / available_bool(true) · comprehensive_test |
with_conversion | Wire type → any app type you impl | price_from(&Cents)? / price_as::<Cents>()? · Configuration · exchange-example |
with_domain_type | Wire type → one fixed Rust path | enc.price(d)?; let d = dec.price()? · l3-book · Configuration |
| Generated enum / composite mappings | SBE enum → your enum, composite → your struct, with renames; exhaustive both ways; NullVal and unknown values are MappingError::NullEnum | .with_enum_mapping(EnumMapping::new("Side", "app::Side")) · .with_composite_mapping(CompositeMapping::new("Leg", "app::Leg")) · App Types · type_mapping_test |
| Source traits | Encode your own type, groups and var-data included, with no DTO and no allocation | .with_source_traits(true) · enc.encode_from(&order)? · Flyweight vs whole struct · source_trait_test |
| Send helpers | Claim → encode → check length and header → commit, aborting on any failure; try-claim or offer transports | OrderEncoder::send(claim, |enc| …)? · send_fixed · sbe_rt::OfferClaim · Aeron try_claim · claim_send_test |
| Domain DTOs | Owned structs + re-encode; allocation-free automatic bulk write for eligible flat groups; var-data via [DomainVarData] | .with_domain_objects(DomainVarData::Strings) · Domain DTOs · domain_objects_test |
AnyMessage + frames | Multi-template + framed streams | AnyMessage::try_decode (bare decode is the same path today) · FrameCursor · demo_any_message |
verify | Full tail bounds check (associated) | CarDecoder::verify(buf)? · demo_try_vs_trusted |
| Schema identity | Id / version / hashes | SCHEMA_ID, SCHEMA_HASH, SCHEMA_SHA256_HEX · generated module header |
| Multi-schema shared types | Dedup across packages | .with_shared_module + generate_multi · exchange-example · multi_schema_versioning_test |
| Keyword-safe names | type → type_ | .with_keyword_append_token("_") · java_parity_features_test |
| XSD-shaped validation | Opt-in stricter check for schema authors | validate_against_sbe_xsd / parse_with_xsd_validation · xsd.rs |
| Zero-alloc hot path | Flyweights + caller buffers; bulk_decode() -> Vec and DomainVarData::Strings do allocate | allocation_count_test |
| Property round-trip | Random messages encode→decode | cargo test -p ergo-sbe --test proptest_roundtrip · proptest_roundtrip |
NullVal → Option<T> | Enum NullVal mapped to Option; wire-identical | .with_null_as_option(…) / .with_all_enums_as_option() — dec.code() -> Option<EventCode> · DTO None writes NullVal; bulk encode uses the same mapping · NullVal design note · Domain DTOs |
| Domain var-data types | CompactString (≤24B inline), SmolStr (O(1) clone), bytes::Bytes (shared) | .with_domain_objects(DomainVarData::CompactStrings) — feature-gated: compact_str, smol_str, bytes · Feature integrations |
| Codec-level type accessors | into_<field>_as_compact_str() / _as_smol_str() / _as_bytes() on consuming stages | Feature-gated behind compact_str, smol_str, bytes · Feature integrations |
| Chrono timestamps | DateTime<Utc> / NaiveDateTime from uint64 + semanticType | .with_domain_type(ConversionSelector::semantic_type("UTCTimestamp"), "chrono::DateTime<chrono::Utc>") — feature-gated: chrono · Timestamps |
| Lean constructor | GenerationConfig::lean("minimal") — no Display/Debug/dispatch, explicit settings preserved | lean() shorthand for new().profile(Lean) · GenerationConfig |
| Must-use lifecycle | #[must_use] on SessionBuilder, AsyncClusterConnect, ClusterClaim | Compile-time guard against discarded builder/connect/claim · SessionBuilder |
| PayloadTooLarge | Typed error when header+payload exceeds Aeron max | ClusterError::PayloadTooLarge { operation, requested, maximum } · Cluster client |
| Zero-alloc offer_parts | Fragmented path uses offer_parts gather — no heap, no payload copy | Stack header + borrowed payload · Cluster client |
| checked_deadline | Fallible deadline: rejects zero/overflow | ClusterError::InvalidTimeout · Cluster client |