verit 0.2.0

Exavian Veritate — zero-copy, self-describing, schema-evolvable binary serialization, safe on untrusted bytes, no unsafe, byte-identical across independent implementations.
Documentation
//! Proof obligation 4a: reads are zero-copy — strings and bytes borrow from
//! the message buffer itself. (4b, the zero-allocation proof, lives in
//! zero_alloc.rs so its global allocation counter isn't polluted by sibling
//! test threads.)

use verit::{encode, Dt, Message, Ref, Resolver, SchemaBuilder, SchemaMode, Value};

fn contains<T>(buf: &[u8], ptr: *const T, len: usize) -> bool {
    let start = buf.as_ptr() as usize;
    let end = start + buf.len();
    let p = ptr as usize;
    p >= start && p + len <= end
}

#[test]
fn strings_and_bytes_borrow_the_message_buffer() {
    let schema = SchemaBuilder::new()
        .add_struct("Rec", vec![(1, "tag", Dt::Str)])
        .add_struct(
            "Doc",
            vec![
                (1, "title", Dt::Str),
                (2, "payload", Dt::Bytes),
                (3, "recs", Dt::list(Dt::named("Rec"))),
            ],
        )
        .build("Doc")
        .unwrap();
    let bytes = encode(
        &schema,
        &Value::Struct(vec![
            (1, Value::str("zero copies given")),
            (2, Value::Bytes(vec![1, 2, 3, 4, 5])),
            (
                3,
                Value::List(vec![Value::Struct(vec![(1, Value::str("inner"))])]),
            ),
        ]),
        SchemaMode::HashOnly,
    )
    .unwrap();

    let resolver = Resolver::identity(&schema).unwrap();
    let msg = Message::parse(&bytes).unwrap();
    let root = msg.root(&resolver).unwrap();

    let title = root.get_str(1).unwrap().unwrap();
    assert_eq!(title, "zero copies given");
    assert!(
        contains(&bytes, title.as_ptr(), title.len()),
        "returned &str must point into the message buffer"
    );

    let payload = root.get_bytes(2).unwrap().unwrap();
    assert!(contains(&bytes, payload.as_ptr(), payload.len()));

    let recs = root.get_list(3).unwrap().unwrap();
    let rec = match recs.get(0).unwrap() {
        Ref::Struct(s) => s,
        other => panic!("expected struct, got {}", other.kind()),
    };
    let inner = rec.get_str(1).unwrap().unwrap();
    assert_eq!(inner, "inner");
    assert!(contains(&bytes, inner.as_ptr(), inner.len()));
}