1 unstable release

0.1.0 Sep 1, 2021

#5 in #lenses

ISC license

2KB

Cambria

Use lenses to maintain forwards and backwards compatibility with your software. Cambria minimizes allocations using rkyv for zero copy deserialization and is formally verified with idris.

Inspired by https://www.inkandswitch.com/cambria.html.

Getting started

Add your lenses to your build.rs file.

use cambria::{Kind, Lens, Lenses, PrimitiveKind};
use std::process::Command;

fn main() {
    let tokens = cambria::precompile("Doc", Lenses::new(vec![
        Lens::Make(Kind::Object),
        Lens::AddProperty("shopping".into()),
        Lens::LensIn(
            "shopping".into(),
            Box::new(Lens::LensMap(Box::new(Lens::Make(Kind::Primitive(
                PrimitiveKind::Text,
            ))))),
        ),
    ]));
    std::fs::write("src/schema.rs", tokens.to_string()).unwrap();
    Command::new("rustfmt")
        .arg("src/schema.rs")
        .arg("--emit")
        .arg("files")
        .status()
        .unwrap();
}

Do some stuff with your schema.

use cambria::{Cambria, Ptr};
use rkyv::ser::serializers::AllocSerializer;
use rkyv::ser::Serializer;

mod schema;
mod schema2;

use schema::Doc;
use schema2::Doc2;

fn main() {
    let doc = Doc {
        done: true,
        xanswer: 42,
        shopping: vec!["cheese".into(), "eggs".into(), "milk".into()],
    };

    let mut ser = AllocSerializer::<256>::default();
    ser.serialize_value(&doc).unwrap();
    let bytes = ser.into_serializer().into_inner().to_vec();
    let ptr = Ptr::new(&bytes, Doc::schema());

    assert_eq!(
        ptr.keys().unwrap().collect::<Vec<_>>(),
        vec!["done", "shopping", "xanswer"]
    );
    let done = ptr.get("done").unwrap().boolean().unwrap();
    assert!(true);

    let answer = ptr.get("xanswer").unwrap().number().unwrap();
    assert_eq!(answer, 42);

    let shopping = ptr.get("shopping").unwrap();
    assert_eq!(shopping.len().unwrap(), 3);
    let cheese = shopping.idx(0).unwrap();
    assert_eq!(cheese.string().unwrap(), "cheese");
    let eggs = shopping.idx(1).unwrap();
    assert_eq!(eggs.string().unwrap(), "eggs");

    let doc2 = Doc2::transform(Doc::lenses(), &bytes).unwrap();
    println!("{:?}", doc);
    println!("{:?}", doc2);
}

License

Apache-2.0 or MIT

No runtime deps