Bulk Arrays

For repeating groups with fixed-size entries (no var-data, no nested groups), generated encoders offer a bulk_add(&[Entry]) path that validates the destination region once and writes every entry.

Car fuelFigures has var-data (usageDescription), so it is not eligible. The nested acceleration group is — each row is mph + seconds only:

#![allow(unused)]
fn main() {
pub fn demo_bulk_add() -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    let mut extras = OptionalExtras::default();
    extras.cruise_control(true);
    let rows = [
        CarPerformanceFiguresAccelerationEntry {
            mph: 30,
            seconds: 4.0,
        },
        CarPerformanceFiguresAccelerationEntry {
            mph: 60,
            seconds: 7.5,
        },
    ];
    let complete_len = CarEncoder::compute_length()
        .fuel_figures_ragged(0, |_| Ok(()))?
        .performance_figures_ragged(1, |pf| {
            pf.add()?.acceleration(|acc| {
                acc.uniform(2)?;
                Ok(())
            })?;
            Ok(())
        })?
        .manufacturer(5)?
        .model(5)?
        .activation_code(3)?
        .encoded_length_with_header();
    const PAD: usize = 256;
    assert!(
        complete_len <= PAD,
        "bulk-add car length {complete_len} exceeds pad {PAD}"
    );
    let mut storage = [0u8; PAD];
    let buf = &mut storage[..complete_len];
    let len = CarEncoder::try_wrap_and_apply_header(buf, 0)?
        .fixed(&CarFixedFields {
            serial_number: 1234,
            model_year: 2013,
            available: true.into(),
            code: Model::A,
            some_numbers: [10, 20, 30, 40],
            vehicle_code: *b"ABCDEF",
            extras,
            engine: Engine::new(
                2000,
                4,
                *b"123",
                0i8,
                false.into(),
                Booster::new(BoostType::TURBO, 210),
            ),
        })
        .fuel_figures(0, |_| Ok(()))?
        .performance_figures(1, |g| {
            g.add(|mut e| {
                e.octane_rating(95);
                e.acceleration(2, |a| {
                    a.bulk_add(&rows)?;
                    Ok(())
                })
            })?;
            Ok(())
        })?
        .manufacturer(b"Honda")?
        .model(b"Civic")?
        .activation_code(b"abc")?
        .encoded_length_with_header();
    assert_eq!(len, complete_len);
    Ok(buf[..len].to_vec())
}
}

(From samples/sbe-feature-tour — compiled and run in that crate's tests.)

bids / asks on the l3-book schema have a nested orders group, so those outer groups are not eligible either. Only a leaf group whose entries are a pure fixed block gets bulk_add.

Constants and MetaAttribute expose schema metadata on every generated type (HeartbeatDecoder::sequence_meta_attribute(MetaAttribute::Presence) and friends). See the generated module after cargo build of the feature-tour sample.