1 unstable release
0.1.0 | Sep 1, 2021 |
---|
#5 in #lenses
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