Experimental WIP

This commit is contained in:
Tony Garnock-Jones 2022-11-16 15:43:49 +01:00
parent ce9d4f2f0c
commit c053e2b9dd
10 changed files with 671 additions and 859 deletions

View File

@ -13,7 +13,7 @@ gitlab = { repository = "preserves/preserves" }
[dependencies] [dependencies]
base64 = "0.13" base64 = "0.13"
bytemuck = "1.12" bytemuck = { version = "1.12", features = ["extern_crate_alloc"] }
dtoa = "0.4" dtoa = "0.4"
lazy_static = "1.4.0" lazy_static = "1.4.0"
num-bigint = "0.4" num-bigint = "0.4"

View File

@ -6,7 +6,6 @@ use std::io;
pub enum Error { pub enum Error {
Io(io::Error), Io(io::Error),
Message(String), Message(String),
InvalidUnicodeScalar(u32),
NumberOutOfRange(BigInt), NumberOutOfRange(BigInt),
MissingCloseDelimiter, MissingCloseDelimiter,
MissingItem, MissingItem,
@ -34,8 +33,6 @@ pub enum ExpectedKind {
Embedded, Embedded,
Option,
UnicodeScalar,
Annotation, Annotation,
} }

View File

@ -3,53 +3,49 @@ pub mod domain;
pub mod error; pub mod error;
pub mod float; pub mod float;
pub mod hex; pub mod hex;
pub mod packed; pub mod merge;
// pub mod packed;
pub mod reader; pub mod reader;
pub mod repr; pub mod repr;
pub mod signed_integer; pub mod signed_integer;
pub mod source; pub mod source;
pub mod text; // pub mod text;
pub mod types; pub mod types;
pub mod writer; pub mod writer;
pub use domain::*; pub use domain::*;
pub use packed::PackedReader; pub use error::Error;
pub use packed::PackedWriter; pub use error::ExpectedKind;
pub use packed::annotated_from_bytes; pub use merge::merge;
pub use packed::annotated_iovalue_from_bytes; pub use merge::merge2;
pub use packed::from_bytes; // pub use packed::PackedReader;
pub use packed::iovalue_from_bytes; // 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::IOValues;
pub use reader::Reader; pub use reader::Reader;
pub use repr::Annotations; pub use repr::Annotations;
pub use repr::ArcValue; pub use repr::ArcValue;
pub use repr::Atom; pub use repr::Atom;
pub use repr::Bytes;
pub use repr::Embedded;
pub use repr::IOValue; pub use repr::IOValue;
pub use repr::Map; pub use repr::Map;
pub use repr::PlainValue;
pub use repr::NoValue; pub use repr::NoValue;
pub use repr::Record; pub use repr::Record;
pub use repr::Set; pub use repr::Set;
pub use repr::Symbol;
pub use repr::Value; pub use repr::Value;
pub use repr::ValueImpl; pub use repr::ValueImpl;
pub use repr::copy_via;
pub use repr::iovalue;
pub use repr::owned;
pub use repr::shell;
pub use repr::value;
pub use signed_integer::SignedInteger; pub use signed_integer::SignedInteger;
pub use source::BinarySource; pub use source::BinarySource;
pub use source::BytesBinarySource; pub use source::BytesBinarySource;
pub use source::IOBinarySource; pub use source::IOBinarySource;
pub use text::TextReader; // pub use text::TextReader;
pub use text::TextWriter; // pub use text::TextWriter;
pub use text::annotated_from_str; // pub use text::annotated_from_str;
pub use text::annotated_iovalue_from_str; // pub use text::annotated_iovalue_from_str;
pub use text::from_str; // pub use text::from_str;
pub use text::iovalue_from_str; // pub use text::iovalue_from_str;
pub use types::AtomClass; pub use types::AtomClass;
pub use types::CompoundClass; pub use types::CompoundClass;
pub use types::ValueClass; pub use types::ValueClass;
@ -64,45 +60,45 @@ mod demo {
// d.get(&k) // d.get(&k)
// } // }
#[test] fn a() { // #[test] fn a() {
let l: PlainValue<NoValue> = "label".parse().unwrap(); // let l: PlainValue<NoValue> = "label".parse().unwrap();
let r = Record::new(l.value_clone(), vec![owned(1), owned(2), owned(3)]); // let r = Record::new(l.value_clone(), vec![owned(1), owned(2), owned(3)]);
let r2 = Record::new(l, vec![owned(1), owned(2), owned(4)]); // let r2 = Record::new(l, vec![owned(1), owned(2), owned(4)]);
let mut v: Map<PlainValue<NoValue>, PlainValue<NoValue>> = Map::new(); // let mut v: Map<PlainValue<NoValue>, PlainValue<NoValue>> = Map::new();
v.insert("\"abc\"".parse().unwrap(), "def".parse().unwrap()); // v.insert("\"abc\"".parse().unwrap(), "def".parse().unwrap());
v.insert("abc".parse().unwrap(), "DEF".parse().unwrap()); // v.insert("abc".parse().unwrap(), "DEF".parse().unwrap());
v.insert(owned(123), "xyz".parse().unwrap()); // v.insert(owned(123), "xyz".parse().unwrap());
v.insert(owned(vec![1, 2, 3]), "{a: 1, b: 2}".parse().unwrap()); // v.insert(owned(vec![1, 2, 3]), "{a: 1, b: 2}".parse().unwrap());
v.insert(owned(r2), "bbb".parse().unwrap()); // v.insert(owned(r2), "bbb".parse().unwrap());
v.insert(owned(r), "<foo bar zot>".parse().unwrap()); // v.insert(owned(r), "<foo bar zot>".parse().unwrap());
let w: &dyn ValueImpl<NoValue> = &v; // let w: &dyn ValueImpl<NoValue> = &v;
println!("GETw abc {:?}", w.get(&"abc")); // println!("GETw abc {:?}", w.get(&"abc"));
println!("GETw 123 {:?}", w.get(&123)); // println!("GETw 123 {:?}", w.get(&123));
println!("GETw qqq {:?}", w.get(&"qqq")); // println!("GETw qqq {:?}", w.get(&"qqq"));
println!("GETv abc {:?}", v.get(&*value(&"abc"))); // println!("GETv abc {:?}", v.get(&*value(&"abc")));
println!("GETv 123 {:?}", v.get(&*value(&123))); // println!("GETv 123 {:?}", v.get(&*value(&123)));
println!("GETv qqq {:?}", v.get(&*value(&"qqq"))); // println!("GETv qqq {:?}", v.get(&*value(&"qqq")));
for (kk, vv) in w.entries() { // for (kk, vv) in w.entries() {
println!("{:#?} ==> {:#?}", kk, vv); // println!("{:#?} ==> {:#?}", kk, vv);
} // }
// { // // {
// use std::io::BufRead; // // use std::io::BufRead;
// for line in std::io::stdin().lock().lines() { // // for line in std::io::stdin().lock().lines() {
// let line = line.unwrap(); // // let line = line.unwrap();
// let key = line.parse::<PlainValue<NoValue>>().unwrap(); // // let key = line.parse::<PlainValue<NoValue>>().unwrap();
// let val = w.get(&key); // // let val = w.get(&key);
// println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line)); // // println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line));
// } // // }
// } // // }
} // }
#[test] fn value_size() { // #[test] fn value_size() {
println!("Value size {}", std::mem::size_of::<Value<'_, NoValue>>()); // println!("Value size {}", std::mem::size_of::<Value<'_, NoValue>>());
println!("&dyn ValueImpl size {}", std::mem::size_of::<&dyn ValueImpl<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>>>()); // println!("Box dyn ValueImpl size {}", std::mem::size_of::<Box<dyn ValueImpl<NoValue>>>());
} // }
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,64 +1,89 @@
use super::Map; use crate::Annotations;
use super::NestedValue; use crate::ArcValue;
use super::Record; use crate::CompoundClass;
use super::Value; use crate::Map;
use crate::Record;
use crate::Value;
use crate::ValueClass;
use crate::ValueImpl;
pub fn merge_seqs<N: NestedValue>(mut a: Vec<N>, mut b: Vec<N>) -> Option<Vec<N>> { pub fn merge_seqs<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(
mut a: Vec<Value<V>>,
mut b: Vec<Value<W>>,
) -> Option<Vec<ArcValue<V::Embedded>>> {
if a.len() > b.len() { if a.len() > b.len() {
std::mem::swap(&mut a, &mut b); std::mem::swap(&mut a, &mut b);
} }
let mut r = vec![]; let mut r = vec![];
let mut bi = b.into_iter(); let mut bi = b.into_iter();
for av in a.into_iter() { for av in a.into_iter() {
r.push(merge2(av, bi.next().unwrap())?); r.push(merge2(&*av, &*bi.next().unwrap())?);
} }
r.extend(bi); r.extend(bi.map(|bv| bv.value_clone()));
Some(r) Some(r)
} }
pub fn merge2<N: NestedValue>(v: N, w: N) -> Option<N> { pub fn merge2<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(v: &Value<V>, w: &Value<W>) -> Option<ArcValue<V::Embedded>> {
let (mut v_anns, v_val) = v.pieces(); let anns = match (v.annotations(), w.annotations()) {
let (w_anns, w_val) = w.pieces(); (Some(va), Some(wa)) => {
match &mut v_anns { let mut a = va.to_vec();
None => v_anns = w_anns, a.extend(wa.to_vec());
Some(vs) => match w_anns { a
None => (),
Some(ws) => vs.extend(ws.into_iter()),
} }
} (Some(va), None) => va.to_vec(),
if v_val == w_val { (None, Some(wa)) => wa.to_vec(),
Some(N::wrap(v_anns, v_val)) (None, None) => vec![],
};
let r = if v == w {
Some(v.peeled().value_clone())
} else { } else {
let maybe_merged = match v_val { match v.value_class() {
Value::Record(rv) => ValueClass::Atomic(_) => None,
Some(Value::Record(Record(merge_seqs(rv.0, w_val.into_record()?.0)?))), ValueClass::Embedded => None,
Value::Sequence(vs) => ValueClass::Compound(CompoundClass::Record) => if w.is_record() {
Some(Value::Sequence(merge_seqs(vs, w_val.into_sequence()?)?)), todo!()
Value::Set(_vs) => // Some(owned(Record::new(merge2(&*v.label(), &*w.label())?,
// merge_seqs(v.iter().collect(), w.iter().collect())?)))
} else {
None
}
ValueClass::Compound(CompoundClass::Sequence) => if w.is_sequence() {
Some(owned(merge_seqs(v.iter().collect(), w.iter().collect())?))
} else {
None
}
ValueClass::Compound(CompoundClass::Set) =>
None, // unsure how to merge sets None, // unsure how to merge sets
Value::Dictionary(vs) => { ValueClass::Compound(CompoundClass::Dictionary) => if w.is_dictionary() {
let mut ws = w_val.into_dictionary()?; let mut ws: Map<_, _> = w.entries().collect();
let mut rs = Map::new(); let mut rs = Map::new();
for (k, vv) in vs.into_iter() { for (k, vv) in v.entries() {
match ws.remove(&k) { match ws.remove(&k) {
Some(wv) => { rs.insert(k, merge2(vv, wv)?); } Some(wv) => { rs.insert(k.value_clone(), merge2(&*vv, &*wv)?); }
None => { rs.insert(k, vv); } None => { rs.insert(k.value_clone(), vv.value_clone()); }
} }
} }
rs.extend(ws.into_iter()); rs.extend(ws.into_iter().map(|(k, wv)| (k.value_clone(), wv.value_clone())));
Some(Value::Dictionary(rs)) Some(owned(rs))
} else {
None
} }
_ => None, }
}; };
maybe_merged.map(|vw| N::wrap(v_anns, vw))
} r.map(|r| if anns.is_empty() {
r
} else {
owned(Annotations::new(r, anns))
})
} }
pub fn merge<N: NestedValue, I: IntoIterator<Item = N>>(vs: I) -> Option<N> { pub fn merge<V: ValueImpl, I: IntoIterator<Item = Value<V>>>(vs: I) -> Option<ArcValue<V::Embedded>> {
let mut vs = vs.into_iter(); let mut vs = vs.into_iter();
let mut v = vs.next().expect("at least one value in merge()"); let mut v = vs.next().expect("at least one value in merge()").value_clone();
for w in vs { for w in vs {
match merge2(v, w) { match merge2(&*v, &*w) {
Some(merged) => v = merged, Some(merged) => v = merged,
None => return None, None => return None,
} }

View File

@ -1,6 +1,6 @@
pub mod constants; pub mod constants;
pub mod reader; pub mod reader;
pub mod view; // pub mod view;
pub mod writer; pub mod writer;
pub use reader::PackedReader; pub use reader::PackedReader;

View File

@ -4,7 +4,7 @@ use std::convert::TryInto;
use std::io; use std::io;
use std::io::Write; use std::io::Write;
use super::constants::Tag; use super::constants::Tag;
use crate::{boundary as B, ValueImpl, Domain, DomainEncode, IOValue, IOValueDomainCodec, Writer}; use crate::{boundary as B, ValueImpl, DomainEncode, IOValue, IOValueDomainCodec, Writer};
struct Buffers<W: io::Write> { struct Buffers<W: io::Write> {
base: W, base: W,
@ -36,9 +36,9 @@ pub struct PackedWriter<W: io::Write>(Buffers<W>);
impl PackedWriter<&mut Vec<u8>> { impl PackedWriter<&mut Vec<u8>> {
#[inline(always)] #[inline(always)]
pub fn encode<D: Domain, Enc: DomainEncode<D>>( pub fn encode<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
enc: &mut Enc, enc: &mut Enc,
v: &dyn ValueImpl<D>, v: &V,
) -> io::Result<Vec<u8>> { ) -> io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
v.write(&mut PackedWriter::new(&mut buf), enc)?; v.write(&mut PackedWriter::new(&mut buf), enc)?;

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,17 @@ use std::convert::TryFrom;
use std::convert::TryInto; use std::convert::TryInto;
use std::fmt; use std::fmt;
#[derive(Debug)]
pub struct OutOfRange(pub BigInt); pub struct OutOfRange(pub BigInt);
impl fmt::Display for OutOfRange {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "The value {:?} is out of range", &self.0)
}
}
impl std::error::Error for OutOfRange {}
impl From<OutOfRange> for crate::error::Error { impl From<OutOfRange> for crate::error::Error {
fn from(e: OutOfRange) -> Self { fn from(e: OutOfRange) -> Self {
crate::error::Error::NumberOutOfRange(e.0) crate::error::Error::NumberOutOfRange(e.0)

View File

@ -1,4 +1,3 @@
use crate::Domain;
use crate::DomainEncode; use crate::DomainEncode;
use crate::IOValue; use crate::IOValue;
use crate::IOValueDomainCodec; use crate::IOValueDomainCodec;
@ -36,10 +35,10 @@ impl std::default::Default for CommaStyle {
} }
impl TextWriter<&mut Vec<u8>> { impl TextWriter<&mut Vec<u8>> {
pub fn fmt_value<D: Domain, Enc: DomainEncode<D>>( pub fn fmt_value<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
f: &mut std::fmt::Formatter<'_>, f: &mut std::fmt::Formatter<'_>,
enc: &mut Enc, enc: &mut Enc,
v: &dyn ValueImpl<D>, v: &V,
) -> io::Result<()> { ) -> io::Result<()> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
let mut w = TextWriter::new(&mut buf); let mut w = TextWriter::new(&mut buf);
@ -49,9 +48,9 @@ impl TextWriter<&mut Vec<u8>> {
|_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter")) |_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter"))
} }
pub fn encode<D: Domain, Enc: DomainEncode<D>>( pub fn encode<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
enc: &mut Enc, enc: &mut Enc,
v: &dyn ValueImpl<D>, v: &V,
) -> io::Result<String> { ) -> io::Result<String> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
v.write(&mut TextWriter::new(&mut buf), enc)?; v.write(&mut TextWriter::new(&mut buf), enc)?;

View File

@ -3,7 +3,6 @@ use std::io;
use crate::AtomClass; use crate::AtomClass;
use crate::CompoundClass; use crate::CompoundClass;
use crate::Domain;
use crate::DomainEncode; use crate::DomainEncode;
use crate::IOValueDomainCodec; use crate::IOValueDomainCodec;
use crate::SignedInteger; use crate::SignedInteger;
@ -70,10 +69,10 @@ pub trait Writer {
fn specialized(&mut self) -> Option<(&str, &mut dyn io::Write)> { None } fn specialized(&mut self) -> Option<(&str, &mut dyn io::Write)> { None }
} }
pub fn write_value<D: Domain, V: ValueImpl<D>>( pub fn write_value<V: ValueImpl>(
w: &mut dyn Writer, w: &mut dyn Writer,
v: V, v: &V,
enc: &mut dyn DomainEncode<D>, enc: &mut dyn DomainEncode<V::Embedded>,
) -> io::Result<()> { ) -> io::Result<()> {
let annotations = v.annotations(); let annotations = v.annotations();
let mut annotation_b = B::Type::default(); let mut annotation_b = B::Type::default();