preserves/implementations/rust/preserves/src/lib.rs

183 lines
5.6 KiB
Rust

pub mod boundary;
pub mod domain;
pub mod error;
pub mod float;
pub mod hex;
pub mod packed;
pub mod reader;
pub mod repr;
pub mod signed_integer;
pub mod source;
pub mod text;
pub mod types;
pub mod writer;
pub use domain::*;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use packed::annotated_from_bytes;
pub use packed::annotated_iovalue_from_bytes;
pub use packed::from_bytes;
pub use packed::iovalue_from_bytes;
pub use reader::IOValues;
pub use reader::Reader;
pub use repr::Annotations;
pub use repr::Atom;
pub use repr::Bytes;
pub use repr::Embedded;
pub use repr::IOValue;
pub use repr::Map;
pub use repr::NoValue;
pub use repr::Record;
pub use repr::Set;
pub use repr::Symbol;
pub use repr::Value;
pub use repr::ValueImpl;
pub use repr::copy_via;
pub use repr::value;
pub use signed_integer::SignedInteger;
pub use source::BinarySource;
pub use source::BytesBinarySource;
pub use source::IOBinarySource;
pub use text::TextReader;
pub use text::TextWriter;
pub use text::annotated_from_str;
pub use text::annotated_iovalue_from_str;
pub use text::from_str;
pub use text::iovalue_from_str;
pub use types::AtomClass;
pub use types::CompoundClass;
pub use types::ValueClass;
pub use writer::Writer;
pub use writer::write_value;
#[cfg(test)]
mod demo {
use crate::*;
// fn getit<'a>(d: &'a dyn ValueImpl<NoValue>, k: &str) -> Option<&'a dyn ValueImpl<NoValue>> {
// d.get(&k)
// }
#[test] fn a() {
let l: Value<NoValue> = "label".parse().unwrap();
let r = Record::new(l.value_clone(), vec![value(1), value(2), value(3)]);
let r2 = Record::new(l, vec![value(1), value(2), value(4)]);
let mut v: Map<Value<NoValue>, Value<NoValue>> = Map::new();
v.insert("\"abc\"".parse().unwrap(), "def".parse().unwrap());
v.insert("abc".parse().unwrap(), "DEF".parse().unwrap());
v.insert(value(123), "xyz".parse().unwrap());
v.insert(vec![1, 2, 3].into(), "{a: 1, b: 2}".parse().unwrap());
v.insert(value(r2), "bbb".parse().unwrap());
v.insert(value(r), "<foo bar zot>".parse().unwrap());
let w: &dyn ValueImpl<NoValue> = &v;
println!("GETw abc {:?}", w.get(&value("abc")));
println!("GETw 123 {:?}", w.get(&value(123)));
println!("GETw qqq {:?}", w.get(&value("qqq")));
println!("GETv abc {:?}", v.get(&value("abc")));
println!("GETv 123 {:?}", v.get(&value(123)));
println!("GETv qqq {:?}", v.get(&value("qqq")));
for (kk, vv) in w.entries() {
println!("{:#?} ==> {:#?}", kk, vv);
}
// {
// use std::io::BufRead;
// for line in std::io::stdin().lock().lines() {
// let line = line.unwrap();
// let key = line.parse::<PlainValue<NoValue>>().unwrap();
// let val = w.get(&key);
// println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line));
// }
// }
}
#[test] fn value_size() {
println!("Value size {}", std::mem::size_of::<Value<NoValue>>());
println!("&dyn ValueImpl size {}", std::mem::size_of::<&dyn ValueImpl<NoValue>>());
println!("Box dyn ValueImpl size {}", std::mem::size_of::<Box<dyn ValueImpl<NoValue>>>());
}
}
#[cfg(test)]
mod test_domain {
use std::io;
use crate::*;
#[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)]
pub enum Dom {
One,
Two,
}
impl Domain for Dom {
type Decode = DebugDomainCodec;
type Encode = DebugDomainCodec;
}
impl std::str::FromStr for Dom {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"One" => Ok(Dom::One),
"Two" => Ok(Dom::Two),
_ => Err(io::Error::new(io::ErrorKind::Other, "cannot parse preserves test domain")),
}
}
}
struct DomCodec;
impl DomainDecode<Dom> for DomCodec {
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
_read_annotations: bool,
) -> io::Result<Dom> {
let v = r.next_iovalue(false)?;
if v.as_bytestring().is_some() {
Ok(Dom::One)
} else {
Ok(Dom::Two)
}
}
}
impl DomainEncode<Dom> for DomCodec {
fn encode_embedded(
&mut self,
w: &mut dyn Writer,
d: &Dom,
) -> io::Result<()> {
match d {
Dom::One => Bytes::new(vec![255, 255, 255, 255]).write(w, self),
Dom::Two => Symbol::new(&format!("Dom::{:?}", d)).write(w, self),
}
}
}
fn dom_as_preserves(v: &Dom) -> io::Result<Value<IOValue>> {
Ok(match v {
Dom::One => value(Bytes::new(vec![255, 255, 255, 255])),
Dom::Two => value(Symbol::new(format!("Dom::{:?}", v))),
})
}
#[test] fn test_one() {
let v = value(vec![value(1),
value(Embedded::new(Dom::One)),
value(2)]);
assert_eq!(PackedWriter::encode_iovalue(&copy_via(&v, &mut dom_as_preserves).unwrap().into()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
}
#[test] fn test_two() {
let v = value(vec![value(1),
value(Embedded::new(Dom::Two)),
value(2)]);
assert_eq!(PackedWriter::encode_iovalue(&copy_via(&v, &mut dom_as_preserves).unwrap().into()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
}
}