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

196 lines
6.0 KiB
Rust

pub mod boundary;
pub mod domain;
pub mod error;
pub mod float;
pub mod hex;
pub mod iovalue;
pub mod merge;
pub mod novalue;
pub mod packed;
pub mod reader;
pub mod repr;
pub mod shell;
pub mod signed_integer;
pub mod source;
pub mod text;
pub mod types;
pub mod writer;
pub use domain::*;
pub use error::Error;
pub use error::ExpectedKind;
pub use iovalue::IOValueDomainDecode;
pub use iovalue::IOValueDomainEncode;
pub use iovalue::IOValues;
pub use merge::merge;
pub use merge::merge2;
pub use novalue::NoValue;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use packed::annotated_from_bytes;
pub use packed::from_bytes;
pub use reader::Reader;
pub use repr::ValueImpl;
pub use repr::ValueReader;
pub use repr::value_eq;
pub use repr::value_cmp;
pub use repr::value_hash;
pub use shell::Annotations;
pub use shell::Atom;
pub use shell::IOValue;
pub use shell::IOValueImpl;
pub use shell::IOValueIso;
pub use shell::Map;
pub use shell::Record;
pub use shell::Set;
pub use shell::Shell;
pub use shell::ShellHandle;
pub use shell::iso_parse;
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::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() -> std::io::Result<()> {
let l: IOValue = "label".parse()?;
let r = IOValue::record(l, vec![1.into(), 2.into(), 3.into()]).wrap();
let r2 = IOValue::record(l, vec![1.into(), 2.into(), 4.into()]).wrap();
let mut v: Map<IOValueIso, IOValueIso> = Map::new();
v.insert(iso_parse("\"abc\"")?, iso_parse("def")?);
v.insert(iso_parse("abc")?, iso_parse("DEF")?);
v.insert(Shell::from(123).into(), iso_parse("xyz")?);
v.insert(Shell::from(vec![1, 2, 3]).into(), iso_parse("{a: 1, b: 2}")?);
v.insert(r2.into(), iso_parse("bbb")?);
v.insert(r.into(), iso_parse("<foo bar zot>")?);
let w: IOValue = IOValueImpl::Dictionary(v).into();
println!("GETw abc {:?}", w.get::<IOValue>(&"abc".into()));
println!("GETw 123 {:?}", w.get::<IOValue>(&123.into()));
println!("GETw qqq {:?}", w.get::<IOValue>(&"qqq".into()));
println!("GETv abc {:?}", v.get(&IOValue::from("abc").iso()));
println!("GETv 123 {:?}", v.get(&IOValue::from(123).iso()));
println!("GETv qqq {:?}", v.get(&IOValue::from("qqq").iso()));
for (kk, vv) in w.entries() {
println!("{:#?} ==> {:#?}", kk, vv);
}
// {
// use std::io::BufRead;
// for line in std::io::stdin().lock().lines() {
// let line = line?;
// let key = line.parse::<PlainValue<NoValue>>()?;
// let val = w.get(&key);
// println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line));
// }
// }
Ok(())
}
#[test] fn value_size() {
println!("IOValue size {}", std::mem::size_of::<IOValue>());
println!("ShellHandle size {}", std::mem::size_of::<ShellHandle<IOValue>>());
println!("Shell size {}", std::mem::size_of::<Shell<IOValue>>());
}
}
#[cfg(test)]
mod test_domain {
use std::io;
use crate::*;
#[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)]
pub enum Dom {
One,
Two,
}
impl<'de> Domain<'de> 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<'de> DomainDecode<'de, Dom> for DomCodec {
fn decode_embedded<R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
_read_annotations: bool,
) -> io::Result<Dom> {
let v = IOValue::read(r, false)?;
if v.value().as_bytestring().is_some() {
Ok(Dom::One)
} else {
Ok(Dom::Two)
}
}
}
impl<'de> DomainEncode<'de, Dom> for DomCodec {
fn encode_embedded(
&mut self,
w: &mut dyn Writer,
d: &Dom,
) -> io::Result<()> {
match d {
Dom::One => Shell::from(vec![255, 255, 255, 255]).write(w, self),
Dom::Two => Shell::symbol(&format!("Dom::{:?}", d)).write(w, self),
}
}
}
fn dom_as_preserves(v: &Dom) -> io::Result<IOValue> {
Ok(match v {
Dom::One => IOValue::from(vec![255, 255, 255, 255]),
Dom::Two => IOValueImpl::symbol(format!("Dom::{:?}", v)).into(),
})
}
#[test] fn test_one() {
let v = Shell::<Dom>::from(
vec![SignedInteger::from(1).into(),
Shell::embedded(Dom::One),
SignedInteger::from(2).into()]).wrap();
assert_eq!(PackedWriter::encode(&IOValue::copy::<Shell::<Dom>, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
}
#[test] fn test_two() {
let v = Shell::<Dom>::from(
vec![SignedInteger::from(1).into(),
Shell::embedded(Dom::Two),
SignedInteger::from(2).into()]).wrap();
assert_eq!(PackedWriter::encode(&IOValue::copy::<Shell::<Dom>, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
}
}