From 1f7895e14e9e7b9b939e290e4609ec989f4939b7 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 20 Nov 2022 21:54:09 +0100 Subject: [PATCH] Good progress --- implementations/rust/preserves/src/domain.rs | 26 +- implementations/rust/preserves/src/iovalue.rs | 22 +- implementations/rust/preserves/src/lib.rs | 93 +++---- .../rust/preserves/src/packed/mod.rs | 8 +- .../rust/preserves/src/packed/view.rs | 67 ++--- .../rust/preserves/src/packed/writer.rs | 9 +- implementations/rust/preserves/src/repr.rs | 62 +++-- implementations/rust/preserves/src/shell.rs | 235 +++++++++++------- .../rust/preserves/src/text/mod.rs | 19 +- .../rust/preserves/src/text/writer.rs | 4 +- implementations/rust/preserves/src/writer.rs | 4 +- 11 files changed, 312 insertions(+), 237 deletions(-) diff --git a/implementations/rust/preserves/src/domain.rs b/implementations/rust/preserves/src/domain.rs index 507a751..0fe9c12 100644 --- a/implementations/rust/preserves/src/domain.rs +++ b/implementations/rust/preserves/src/domain.rs @@ -3,12 +3,12 @@ use std::io; use super::Reader; use super::Writer; -pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone { - type Decode: for<'de> DomainDecode<'de, Self> + Default; - type Encode: DomainEncode + Default; +pub trait Domain<'de>: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone { + type Decode: DomainDecode<'de, Self> + Default; + type Encode: DomainEncode<'de, Self> + Default; } -pub trait DomainDecode<'de, D: Domain> { +pub trait DomainDecode<'de, D: Domain<'de>> { fn decode_embedded + ?Sized>( &mut self, r: &mut R, @@ -16,7 +16,7 @@ pub trait DomainDecode<'de, D: Domain> { ) -> io::Result; } -pub trait DomainEncode { +pub trait DomainEncode<'de, D: Domain<'de>> { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -24,7 +24,7 @@ pub trait DomainEncode { ) -> io::Result<()>; } -impl<'a, 'de, D: Domain, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a mut T { +impl<'a, 'de, D: Domain<'de>, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a mut T { fn decode_embedded + ?Sized>( &mut self, r: &mut R, @@ -34,7 +34,7 @@ impl<'a, 'de, D: Domain, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a m } } -impl<'a, D: Domain, T: DomainEncode> DomainEncode for &'a mut T { +impl<'a, 'de, D: Domain<'de>, T: DomainEncode<'de, D>> DomainEncode<'de, D> for &'a mut T { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -47,7 +47,7 @@ impl<'a, D: Domain, T: DomainEncode> DomainEncode for &'a mut T { #[derive(Default)] pub struct DefaultDomainCodec; -impl<'de, D: Domain> DomainDecode<'de, D> for DefaultDomainCodec { +impl<'de, D: Domain<'de>> DomainDecode<'de, D> for DefaultDomainCodec { fn decode_embedded + ?Sized>( &mut self, r: &mut R, @@ -57,7 +57,7 @@ impl<'de, D: Domain> DomainDecode<'de, D> for DefaultDomainCodec { } } -impl DomainEncode for DefaultDomainCodec { +impl<'de, D: Domain<'de>> DomainEncode<'de, D> for DefaultDomainCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -70,7 +70,7 @@ impl DomainEncode for DefaultDomainCodec { #[derive(Default)] pub struct DebugDomainCodec; -impl<'de, Err: Into, D: Domain + std::str::FromStr> DomainDecode<'de, D> for DebugDomainCodec { +impl<'de, Err: Into, D: Domain<'de> + std::str::FromStr> DomainDecode<'de, D> for DebugDomainCodec { fn decode_embedded + ?Sized>( &mut self, r: &mut R, @@ -80,7 +80,7 @@ impl<'de, Err: Into, D: Domain + std::str::FromStr> Domain } } -impl DomainEncode for DebugDomainCodec { +impl<'de, D: Domain<'de>> DomainEncode<'de, D> for DebugDomainCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -93,7 +93,7 @@ impl DomainEncode for DebugDomainCodec { #[derive(Default)] pub struct NoEmbeddedDomainCodec; -impl<'de, D: Domain> DomainDecode<'de, D> for NoEmbeddedDomainCodec { +impl<'de, D: Domain<'de>> DomainDecode<'de, D> for NoEmbeddedDomainCodec { fn decode_embedded + ?Sized>( &mut self, _r: &mut R, @@ -103,7 +103,7 @@ impl<'de, D: Domain> DomainDecode<'de, D> for NoEmbeddedDomainCodec { } } -impl DomainEncode for NoEmbeddedDomainCodec { +impl<'de, D: Domain<'de>> DomainEncode<'de, D> for NoEmbeddedDomainCodec { fn encode_embedded( &mut self, _w: &mut dyn Writer, diff --git a/implementations/rust/preserves/src/iovalue.rs b/implementations/rust/preserves/src/iovalue.rs index 5ae8fcf..4e4da53 100644 --- a/implementations/rust/preserves/src/iovalue.rs +++ b/implementations/rust/preserves/src/iovalue.rs @@ -9,23 +9,23 @@ use crate::ValueImpl; use crate::Writer; use crate::ValueReader; -pub struct IOValueDomainDecode(PhantomData); -pub struct IOValueDomainEncode(PhantomData); +pub struct IOValueDomainDecode<'de, V: ValueReader<'de>>(PhantomData<&'de V>); +pub struct IOValueDomainEncode<'de, V: ValueImpl<'de>>(PhantomData<&'de V>); -impl Default for IOValueDomainDecode { fn default() -> Self { Self(PhantomData) } } -impl Default for IOValueDomainEncode { fn default() -> Self { Self(PhantomData) } } +impl<'de, V: ValueReader<'de>> Default for IOValueDomainDecode<'de, V> { fn default() -> Self { Self(PhantomData) } } +impl<'de, V: ValueImpl<'de>> Default for IOValueDomainEncode<'de, V> { fn default() -> Self { Self(PhantomData) } } -impl<'de, V: ValueReader> DomainDecode<'de, as ValueImpl>::IOEmbedded> for IOValueDomainDecode { +impl<'de, V: ValueReader<'de>> DomainDecode<'de, >::IOEmbedded> for IOValueDomainDecode<'de, V> { fn decode_embedded + ?Sized>( &mut self, r: &mut R, read_annotations: bool, - ) -> io::Result< as ValueImpl>::IOEmbedded> { + ) -> io::Result<>::IOEmbedded> { Ok(V::read_iovalue(r, read_annotations)?) } } -impl DomainEncode for IOValueDomainEncode { +impl<'de, V: ValueImpl<'de>> DomainEncode<'de, V::IOEmbedded> for IOValueDomainEncode<'de, V> { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -35,13 +35,13 @@ impl DomainEncode for IOValueDomainEncode { } } -pub struct IOValues<'de, V: ValueReader, R: Reader<'de>> { +pub struct IOValues<'de, V: ValueReader<'de>, R: Reader<'de>> { pub reader: R, pub read_annotations: bool, phantom: PhantomData<&'de V>, } -impl<'de, V: ValueReader, R: Reader<'de>> IOValues<'de, V, R> { +impl<'de, V: ValueReader<'de>, R: Reader<'de>> IOValues<'de, V, R> { pub fn new(reader: R) -> Self { IOValues { reader, @@ -56,8 +56,8 @@ impl<'de, V: ValueReader, R: Reader<'de>> IOValues<'de, V, R> { } } -impl<'de, V: ValueReader, R: Reader<'de>> Iterator for IOValues<'de, V, R> { - type Item = io::Result< as ValueImpl>::IOEmbedded>; +impl<'de, V: ValueReader<'de>, R: Reader<'de>> Iterator for IOValues<'de, V, R> { + type Item = io::Result<>::IOEmbedded>; fn next(&mut self) -> Option { match self.reader.peek_class() { diff --git a/implementations/rust/preserves/src/lib.rs b/implementations/rust/preserves/src/lib.rs index de38f59..b63b236 100644 --- a/implementations/rust/preserves/src/lib.rs +++ b/implementations/rust/preserves/src/lib.rs @@ -5,6 +5,7 @@ pub mod float; pub mod hex; pub mod iovalue; pub mod merge; +pub mod novalue; pub mod packed; pub mod reader; pub mod repr; @@ -23,6 +24,7 @@ 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; @@ -36,11 +38,14 @@ 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; @@ -63,45 +68,47 @@ mod demo { // d.get(&k) // } - // #[test] fn a() { - // let l: PlainValue = "label".parse().unwrap(); - // 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)]); + #[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, PlainValue> = Map::new(); - // 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(vec![1, 2, 3]), "{a: 1, b: 2}".parse().unwrap()); - // v.insert(owned(r2), "bbb".parse().unwrap()); - // v.insert(owned(r), "".parse().unwrap()); - // let w: &dyn ValueImpl = &v; - // println!("GETw abc {:?}", w.get(&"abc")); - // println!("GETw 123 {:?}", w.get(&123)); - // println!("GETw qqq {:?}", w.get(&"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); - // } + let mut v: Map = 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("")?); + let w: IOValue = IOValueImpl::Dictionary(v).into(); + println!("GETw abc {:?}", w.get::(&"abc".into())); + println!("GETw 123 {:?}", w.get::(&123.into())); + println!("GETw qqq {:?}", w.get::(&"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.unwrap(); - // // let key = line.parse::>().unwrap(); - // // let val = w.get(&key); - // // println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line)); - // // } - // // } - // } + // { + // use std::io::BufRead; + // for line in std::io::stdin().lock().lines() { + // let line = line?; + // let key = line.parse::>()?; + // let val = w.get(&key); + // println!("{:?} == {:?} ==> {:?} == {:?}", line, &key, val, getit(&v, &line)); + // } + // } - // #[test] fn value_size() { - // println!("Value size {}", std::mem::size_of::>()); - // println!("&dyn ValueImpl size {}", std::mem::size_of::<&dyn ValueImpl>()); - // println!("Box dyn ValueImpl size {}", std::mem::size_of::>>()); - // } + Ok(()) + } + + #[test] fn value_size() { + println!("IOValue size {}", std::mem::size_of::()); + println!("ShellHandle size {}", std::mem::size_of::>()); + println!("Shell size {}", std::mem::size_of::>()); + } } #[cfg(test)] @@ -115,7 +122,7 @@ mod test_domain { Two, } - impl Domain for Dom { + impl<'de> Domain<'de> for Dom { type Decode = DebugDomainCodec; type Encode = DebugDomainCodec; } @@ -133,13 +140,13 @@ mod test_domain { struct DomCodec; - impl DomainDecode for DomCodec { - fn decode_embedded<'de, R: Reader<'de> + ?Sized>( + impl<'de> DomainDecode<'de, Dom> for DomCodec { + fn decode_embedded + ?Sized>( &mut self, r: &mut R, _read_annotations: bool, ) -> io::Result { - let v = read_iovalue(r, false)?; + let v = IOValue::read(r, false)?; if v.value().as_bytestring().is_some() { Ok(Dom::One) } else { @@ -148,7 +155,7 @@ mod test_domain { } } - impl DomainEncode for DomCodec { + impl<'de> DomainEncode<'de, Dom> for DomCodec { fn encode_embedded( &mut self, w: &mut dyn Writer, @@ -173,7 +180,7 @@ mod test_domain { vec![SignedInteger::from(1).into(), Shell::embedded(Dom::One), SignedInteger::from(2).into()]).wrap(); - assert_eq!(PackedWriter::encode_iovalue(&IOValue::copy::, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(), + assert_eq!(PackedWriter::encode(&IOValue::copy::, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(), [0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]); } @@ -182,7 +189,7 @@ mod test_domain { vec![SignedInteger::from(1).into(), Shell::embedded(Dom::Two), SignedInteger::from(2).into()]).wrap(); - assert_eq!(PackedWriter::encode_iovalue(&IOValue::copy::, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(), + assert_eq!(PackedWriter::encode(&IOValue::copy::, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(), [0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]); } } diff --git a/implementations/rust/preserves/src/packed/mod.rs b/implementations/rust/preserves/src/packed/mod.rs index 0c6a395..ea03938 100644 --- a/implementations/rust/preserves/src/packed/mod.rs +++ b/implementations/rust/preserves/src/packed/mod.rs @@ -16,16 +16,16 @@ use crate::Shell; use crate::ShellHandle; use crate::ValueReader; -pub fn from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>( +pub fn from_bytes<'de, D: Domain<'de>, Dec: DomainDecode<'de, D>>( bs: &'de [u8], decode_embedded: &mut Dec, ) -> io::Result> { - Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), false, decode_embedded)?) + Ok(Shell::read_domain(&mut BytesBinarySource::new(bs).packed(), false, decode_embedded)?) } -pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>( +pub fn annotated_from_bytes<'de, D: Domain<'de>, Dec: DomainDecode<'de, D>>( bs: &'de [u8], decode_embedded: &mut Dec, ) -> io::Result> { - Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?) + Ok(Shell::read_domain(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?) } diff --git a/implementations/rust/preserves/src/packed/view.rs b/implementations/rust/preserves/src/packed/view.rs index bdf658b..e172a41 100644 --- a/implementations/rust/preserves/src/packed/view.rs +++ b/implementations/rust/preserves/src/packed/view.rs @@ -14,15 +14,18 @@ use crate::BinarySource; use crate::BytesBinarySource; use crate::Domain; use crate::DomainDecode; +use crate::DomainEncode; use crate::NoEmbeddedDomainCodec; use crate::PackedWriter; use crate::SignedInteger; use crate::ValueClass; use crate::ValueImpl; +use crate::Writer; use crate::error; use crate::error::io_eof; use crate::reader::NextToken; use crate::value_eq; +use crate::write_value; use super::constants::Tag; @@ -38,7 +41,7 @@ struct IndexedRepr<'de, D> { phantom: PhantomData<&'de ()>, } -pub struct View<'de, D: Domain> { +pub struct View<'de, D: Domain<'de>> { repr: Arc>, annotation_offset: usize, value_range: Range, @@ -53,7 +56,7 @@ struct IndexInProgress<'dec, D, Dec> { dec: &'dec mut Dec, } -struct Indexer<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> { +struct Indexer<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D>> { packed: &'de [u8], offset: usize, index: Option>, @@ -86,7 +89,7 @@ fn varint(packed: &[u8], mut i: usize) -> io::Result<(u64, usize)> { } } -impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Indexer<'de, 'dec, D, Dec> { +impl<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D>> Indexer<'de, 'dec, D, Dec> { fn skip_annotations(&mut self) -> io::Result<()> { loop { if tag_at(&self.packed, self.offset)? == Tag::Annotation { @@ -167,7 +170,7 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Indexer<'de, 'dec, D, Dec> } } -impl<'de, D: Domain> IndexedRepr<'de, D> { +impl<'de, D: Domain<'de>> IndexedRepr<'de, D> { fn trim(&self, range: Range) -> Arc> { Arc::new(IndexedRepr { packed: self.packed.as_ref()[range.clone()].to_vec().into(), @@ -190,19 +193,19 @@ impl<'de, D: Domain> IndexedRepr<'de, D> { } } -impl<'de, D: Domain> View<'de, D> { +impl<'de, D: Domain<'de>> View<'de, D> { pub fn new>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>) -> io::Result { Self::new_offset(packed, dec, 0) } - pub fn trim(&self) -> View<'static, D> { - View { - repr: self.repr.trim(self.annotation_offset .. self.value_range.end), - annotation_offset: 0, - value_range: (self.value_range.start - self.annotation_offset - .. self.value_range.end - self.annotation_offset), - } - } + // pub fn trim(&self) -> View<'static, D> { + // View { + // repr: self.repr.trim(self.annotation_offset .. self.value_range.end), + // annotation_offset: 0, + // value_range: (self.value_range.start - self.annotation_offset + // .. self.value_range.end - self.annotation_offset), + // } + // } pub fn new_offset>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>, offset: usize) -> io::Result { let mut indexer = Indexer { @@ -299,12 +302,12 @@ impl<'de, D: Domain> View<'de, D> { } } -impl<'de, D: Domain> Domain for View<'de, D> { +impl<'de, D: Domain<'de>> Domain<'de> for View<'de, D> { type Decode = NoEmbeddedDomainCodec; type Encode = NoEmbeddedDomainCodec; } -impl<'de, D: Domain> Clone for View<'de, D> { +impl<'de, D: Domain<'de>> Clone for View<'de, D> { fn clone(&self) -> Self { View { repr: self.repr.clone(), @@ -314,10 +317,10 @@ impl<'de, D: Domain> Clone for View<'de, D> { } } -impl<'de, D: Domain> ValueImpl for View<'de, D> { +impl<'de, D: Domain<'de>> ValueImpl<'de> for View<'de, D> { type Handle = Self; type Embedded = D; - type Mapped = View<'de, E>; + type Mapped> = View<'de, E>; type Items<'a> = ViewIterator> where Self: 'a; type Entries<'a> = DictionaryAdapter> where Self: 'a; type IOEmbedded = IOView<'de>; @@ -326,7 +329,7 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { self } - fn write(&self, w: &mut dyn crate::Writer, enc: &mut dyn crate::DomainEncode) -> io::Result<()> { + fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { match w.specialized() { Some(("packed", mut w)) => { if let Some(embedded) = &self.repr.index.embedded { @@ -342,7 +345,7 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { w.write_all(&self.repr.packed.as_ref()[self.annotation_offset .. self.value_range.end]) } } - _ => crate::write_value(w, self, enc) + _ => write_value(w, self, enc) } } @@ -454,7 +457,7 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { self.tag() == Tag::Set } - fn has>(&self, v: &E::Handle) -> bool { + fn has>(&self, v: &E::Handle) -> bool { self.iter().find(|e| value_eq(v.borrow(), e)).is_some() } @@ -462,7 +465,7 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { self.tag() == Tag::Dictionary } - fn get>(&self, k: &K::Handle) -> Option { + fn get>(&self, k: &K::Handle) -> Option { for (kk, vv) in self.entries() { if value_eq(k.borrow(), &kk) { return Some(vv); } } @@ -492,7 +495,7 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { } } - fn annotations(&self) -> Option as ValueImpl>::Handle]>> { + fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>> { if self.value_range.start == self.annotation_offset { None } else { @@ -515,20 +518,20 @@ impl<'de, D: Domain> ValueImpl for View<'de, D> { } } - fn copy(w: &E::Handle, f: &mut F) -> Result + fn copy, F, Err>(w: &E::Handle, f: &mut F) -> Result where F: FnMut(&E::Embedded) -> Result { todo!() } - fn map_embedded(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl>::Handle, Err> + fn map_embedded, F, Err>(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl<'de>>::Handle, Err> where F: FnMut(&Self::Embedded) -> Result { todo!() } } -crate::impl_value_methods!({'de, D: Domain}, View<'de, D>); +crate::impl_value_methods!({'de, D: Domain<'de>}, View<'de, D>); impl<'de> Clone for IOView<'de> { fn clone(&self) -> Self { @@ -568,7 +571,7 @@ impl<'de> PartialEq for IOView<'de> { impl<'de> Eq for IOView<'de> {} -impl<'de> Domain for IOView<'de> { +impl<'de> Domain<'de> for IOView<'de> { type Decode = NoEmbeddedDomainCodec; type Encode = NoEmbeddedDomainCodec; } @@ -591,14 +594,14 @@ impl<'de> AsRef> for IOView<'de> { } } -pub struct ViewStream<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D> = ::Decode> { +pub struct ViewStream<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D> = >::Decode> { buf: Cow<'de, [u8]>, dec: Option<&'dec mut Dec>, offset: usize, phantom: PhantomData<&'de D>, } -impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> ViewStream<'de, 'dec, D, Dec> { +impl<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D>> ViewStream<'de, 'dec, D, Dec> { pub fn new(buf: Cow<'de, [u8]>, dec: Option<&'dec mut Dec>) -> Self { ViewStream { buf, @@ -609,7 +612,7 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> ViewStream<'de, 'dec, D, D } } -impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Iterator for ViewStream<'de, 'dec, D, Dec> { +impl<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D>> Iterator for ViewStream<'de, 'dec, D, Dec> { type Item = io::Result>; fn next(&mut self) -> Option { @@ -632,13 +635,13 @@ pub struct ViewIterator { offset: usize, } -impl<'de, D: Domain> ViewIterator> { +impl<'de, D: Domain<'de>> ViewIterator> { pub fn inner_new(repr: &Arc>, offset: usize) -> Self { ViewIterator { repr: Arc::clone(repr), offset } } } -impl<'de, D: Domain> Iterator for ViewIterator> { +impl<'de, D: Domain<'de>> Iterator for ViewIterator> { type Item = View<'de, D>; fn next(&mut self) -> Option { @@ -654,7 +657,7 @@ impl<'de, D: Domain> Iterator for ViewIterator> { pub struct DictionaryAdapter(pub ViewIterator); -impl<'de, D: Domain> Iterator for DictionaryAdapter> { +impl<'de, D: Domain<'de>> Iterator for DictionaryAdapter> { type Item = (View<'de, D>, View<'de, D>); fn next(&mut self) -> Option { diff --git a/implementations/rust/preserves/src/packed/writer.rs b/implementations/rust/preserves/src/packed/writer.rs index 74c70b4..f685aef 100644 --- a/implementations/rust/preserves/src/packed/writer.rs +++ b/implementations/rust/preserves/src/packed/writer.rs @@ -4,7 +4,7 @@ use std::convert::TryInto; use std::io; use std::io::Write; use super::constants::Tag; -use crate::{boundary as B, ValueImpl, DomainEncode, Writer}; +use crate::{boundary as B, ValueImpl, DomainEncode, Writer, DefaultDomainCodec}; struct Buffers { base: W, @@ -36,7 +36,7 @@ pub struct PackedWriter(Buffers); impl PackedWriter<&mut Vec> { #[inline(always)] - pub fn encode>( + pub fn encode_domain<'de, V: ValueImpl<'de>, Enc: DomainEncode<'de, V::Embedded>>( enc: &mut Enc, v: &V, ) -> io::Result> { @@ -44,6 +44,11 @@ impl PackedWriter<&mut Vec> { v.write(&mut PackedWriter::new(&mut buf), enc)?; Ok(buf) } + + #[inline(always)] + pub fn encode<'de, V: ValueImpl<'de>>(v: &V) -> io::Result> { + Self::encode_domain(&mut DefaultDomainCodec, v) + } } pub fn varint(w: &mut W, mut v: u64) -> io::Result { diff --git a/implementations/rust/preserves/src/repr.rs b/implementations/rust/preserves/src/repr.rs index d91a05f..519b055 100644 --- a/implementations/rust/preserves/src/repr.rs +++ b/implementations/rust/preserves/src/repr.rs @@ -7,6 +7,7 @@ use std::hash::Hash; use std::hash::Hasher; use std::io; +use crate::DefaultDomainCodec; use crate::DomainDecode; use crate::Reader; use crate::error::ReadError; @@ -23,31 +24,38 @@ use crate::write_value; use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64}; -pub trait ValueReader { - type Impl<'de>: ValueImpl; +pub trait ValueReader<'de> { + type Impl: ValueImpl<'de>; - fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode< as ValueImpl>::Embedded>>( + fn read_impl + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, - ) -> Result, ReadError>; + ) -> Result; - fn read<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode< as ValueImpl>::Embedded>>( + fn read_domain + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, - ) -> Result< as ValueImpl>::Handle, ReadError> { + ) -> Result<>::Handle, ReadError> { Ok(Self::read_impl(r, read_annotations, dec)?.wrap()) } - fn read_iovalue<'de, R: Reader<'de> + ?Sized>( + fn read + ?Sized>( r: &mut R, read_annotations: bool, - ) -> Result< as ValueImpl>::IOEmbedded, ReadError>; + ) -> Result<>::Handle, ReadError> { + Self::read_domain(r, read_annotations, &mut DefaultDomainCodec) + } - fn gather_annotations<'de, R: Reader<'de> + ?Sized>( + fn read_iovalue + ?Sized>( r: &mut R, - ) -> io::Result as ValueImpl>::Mapped< as ValueImpl>::IOEmbedded> as ValueImpl>::Handle>, ValueClass)>> { + read_annotations: bool, + ) -> Result<>::IOEmbedded, ReadError>; + + fn gather_annotations + ?Sized>( + r: &mut R, + ) -> io::Result>::Mapped<>::IOEmbedded> as ValueImpl<'de>>::Handle>, ValueClass)>> { let mut anns = Vec::new(); loop { match r.peek_class()? { @@ -64,17 +72,17 @@ pub trait ValueReader { } /// Atomic values from the specification. -pub trait ValueImpl: Sized { +pub trait ValueImpl<'de>: Sized { type Handle: Borrow + Clone + From + Hash + Eq + Ord + PartialEq + PartialOrd; - type Embedded: Domain; - type Mapped: ValueImpl; + type Embedded: Domain<'de>; + type Mapped>: ValueImpl<'de, Embedded = E>; type Items<'a>: Iterator + 'a where Self: 'a; type Entries<'a>: Iterator + 'a where Self: 'a; - type IOEmbedded: From< as ValueImpl>::Handle> + - Into< as ValueImpl>::Handle> + - AsRef< as ValueImpl>::Handle> + - Domain; + type IOEmbedded: From< as ValueImpl<'de>>::Handle> + + Into< as ValueImpl<'de>>::Handle> + + AsRef< as ValueImpl<'de>>::Handle> + + Domain<'de>; fn wrap(self) -> Self::Handle; @@ -114,29 +122,29 @@ pub trait ValueImpl: Sized { fn iter(&self) -> Self::Items<'_>; fn is_set(&self) -> bool; - fn has>(&self, _v: &E::Handle) -> bool; + fn has>(&self, _v: &E::Handle) -> bool; fn is_dictionary(&self) -> bool; - fn get>(&self, _k: &K::Handle) -> Option; + fn get>(&self, _k: &K::Handle) -> Option; fn entries(&self) -> Self::Entries<'_>; fn as_embedded(&self) -> Option>; // INVARIANT: return Some() *only* when the contained collection is nonempty - fn annotations(&self) -> Option as ValueImpl>::Handle]>>; + fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>>; fn peeled(v: &Self::Handle) -> Self::Handle; - fn copy(w: &E::Handle, f: &mut F) -> Result + fn copy, F, Err>(w: &E::Handle, f: &mut F) -> Result where F: FnMut(&E::Embedded) -> Result; - fn map_embedded(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl>::Handle, Err> + fn map_embedded, F, Err>(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl<'de>>::Handle, Err> where F: FnMut(&Self::Embedded) -> Result; } -pub fn value_hash(v: &V, state: &mut H) { +pub fn value_hash<'de, V: ValueImpl<'de>, H: Hasher>(v: &V, state: &mut H) { match v.value_class() { ValueClass::Atomic(a) => match a { AtomClass::Boolean => v.as_boolean().unwrap().hash(state), @@ -171,7 +179,7 @@ pub fn value_hash(v: &V, state: &mut H) { } // TODO: when unstable feature iter_order_by stabilises, use that instead -fn iters_eq>(i: &V::Items<'_>, j: &W::Items<'_>) -> bool { +fn iters_eq<'de, V: ValueImpl<'de>, W: ValueImpl<'de, Embedded = V::Embedded>>(i: &V::Items<'_>, j: &W::Items<'_>) -> bool { loop { match i.next() { None => return j.next().is_none(), @@ -183,7 +191,7 @@ fn iters_eq>(i: &V::Items<'_> } } -pub fn value_eq>(v: &V, w: &W) -> bool { +pub fn value_eq<'de, V: ValueImpl<'de>, W: ValueImpl<'de, Embedded = V::Embedded>>(v: &V, w: &W) -> bool { let cls = v.value_class(); if cls != w.value_class() { return false; } match cls { @@ -227,7 +235,7 @@ pub fn value_eq>(v: &V, w: &W } // TODO: when unstable feature iter_order_by stabilises, use that instead -fn iters_cmp>(i: &V::Items<'_>, j: &W::Items<'_>) -> Ordering { +fn iters_cmp<'de, V: ValueImpl<'de>, W: ValueImpl<'de, Embedded = V::Embedded>>(i: &V::Items<'_>, j: &W::Items<'_>) -> Ordering { loop { match i.next() { None => return if j.next().is_none() { Ordering::Equal } else { Ordering::Less }, @@ -242,7 +250,7 @@ fn iters_cmp>(i: &V::Items<'_ } } -pub fn value_cmp>(v: &V, w: &W) -> Ordering { +pub fn value_cmp<'de, V: ValueImpl<'de>, W: ValueImpl<'de, Embedded = V::Embedded>>(v: &V, w: &W) -> Ordering { let cls = v.value_class(); cls.cmp(&w.value_class()).then_with(|| match cls { ValueClass::Atomic(a) => match a { diff --git a/implementations/rust/preserves/src/shell.rs b/implementations/rust/preserves/src/shell.rs index bac806c..dfecc5f 100644 --- a/implementations/rust/preserves/src/shell.rs +++ b/implementations/rust/preserves/src/shell.rs @@ -11,10 +11,14 @@ use std::sync::Arc; use bytemuck::TransparentWrapper; use crate::AtomClass; +use crate::BinarySource; +use crate::BytesBinarySource; use crate::CompoundClass; +use crate::DefaultDomainCodec; use crate::Domain; use crate::DomainDecode; use crate::DomainEncode; +use crate::Error; use crate::ExpectedKind; use crate::IOValueDomainDecode; use crate::IOValueDomainEncode; @@ -22,12 +26,12 @@ use crate::Reader; use crate::SignedInteger; use crate::ValueClass; use crate::ValueImpl; +use crate::ValueReader; use crate::Writer; use crate::boundary as B; use crate::error::ReadError; use crate::error::io_eof; use crate::impl_value_methods; -use crate::repr::ValueReader; pub use std::collections::BTreeSet as Set; pub use std::collections::BTreeMap as Map; @@ -111,10 +115,23 @@ impl<'a> From for Atom<'a> { fn from(v: String) -> Self { Atom::String(C impl<'a> From<&'a [u8]> for Atom<'a> { fn from(v: &'a [u8]) -> Self { Atom::ByteString(Cow::Borrowed(v)) } } impl<'a> From> for Atom<'a> { fn from(v: Vec) -> Self { Atom::ByteString(Cow::Owned(v)) } } +impl<'a> From for Atom<'a> { fn from(i: i8) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: u8) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: i16) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: u16) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: i32) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: u32) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: i64) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: u64) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: i128) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: u128) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: isize) -> Self { SignedInteger::from(i).into() } } +impl<'a> From for Atom<'a> { fn from(i: usize) -> Self { SignedInteger::from(i).into() } } + macro_rules! from_atom_ref_impl { - ($t:ty, $p:pat, $e:expr, $err:expr) => { + ($t:ty, $p:pat, $e:expr, $errty:ty, $err:expr) => { impl<'r, 'a> TryFrom<&'r Atom<'a>> for $t { - type Error = ExpectedKind; + type Error = $errty; fn try_from(value: &'r Atom<'a>) -> Result { match value { $p => Ok($e), @@ -124,12 +141,25 @@ macro_rules! from_atom_ref_impl { } }; } -from_atom_ref_impl!(bool, Atom::Boolean(b), *b, ExpectedKind::Boolean); -from_atom_ref_impl!(f32, Atom::Float(f), *f, ExpectedKind::Float); -from_atom_ref_impl!(f64, Atom::Double(d), *d, ExpectedKind::Double); -from_atom_ref_impl!(&'a SignedInteger, Atom::SignedInteger(i), i.as_ref(), ExpectedKind::SignedInteger); -from_atom_ref_impl!(&'a str, Atom::String(s), s.as_ref(), ExpectedKind::String); -from_atom_ref_impl!(&'a [u8], Atom::ByteString(bs), bs.as_ref(), ExpectedKind::ByteString); +from_atom_ref_impl!(bool, Atom::Boolean(b), *b, ExpectedKind, ExpectedKind::Boolean); +from_atom_ref_impl!(f32, Atom::Float(f), *f, ExpectedKind, ExpectedKind::Float); +from_atom_ref_impl!(f64, Atom::Double(d), *d, ExpectedKind, ExpectedKind::Double); +from_atom_ref_impl!(&'a SignedInteger, Atom::SignedInteger(i), i.as_ref(), ExpectedKind, ExpectedKind::SignedInteger); +from_atom_ref_impl!(&'a str, Atom::String(s), s.as_ref(), ExpectedKind, ExpectedKind::String); +from_atom_ref_impl!(&'a [u8], Atom::ByteString(bs), bs.as_ref(), ExpectedKind, ExpectedKind::ByteString); + +from_atom_ref_impl!(i8, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(u8, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(i16, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(u16, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(i32, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(u32, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(i64, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(u64, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(i128, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(u128, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(isize, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); +from_atom_ref_impl!(usize, Atom::SignedInteger(i), i.as_ref().try_into()?, Error, Error::Expected(ExpectedKind::SignedInteger)); macro_rules! from_atom_val_impl { ($t:ty, $p:pat, $e:expr, $err:expr) => { @@ -152,22 +182,22 @@ from_atom_val_impl!(Cow<'a, str>, Atom::String(s), s, ExpectedKind::String); from_atom_val_impl!(Cow<'a, [u8]>, Atom::ByteString(bs), bs, ExpectedKind::ByteString); pub type ShellHandle<'a, D> = Arc>; -pub enum Shell<'a, D: Domain> { - Atom(Atom<'a>), - Record(Record>), - Sequence(Vec>), - Set(Set>), - Dictionary(Map, ShellHandle<'a, D>>), +pub enum Shell<'de, D: Domain<'de>> { + Atom(Atom<'de>), + Record(Record>), + Sequence(Vec>), + Set(Set>), + Dictionary(Map, ShellHandle<'de, D>>), Embedded(D), - Annotated(Annotations), + Annotated(Annotations<'de, Self>), } -impl<'a, D: Domain> Shell<'a, D> { - pub fn record(label: ShellHandle<'a, D>, fields: Vec>) -> Self { +impl<'de, D: Domain<'de>> Shell<'de, D> { + pub fn record(label: ShellHandle<'de, D>, fields: Vec>) -> Self { Shell::Record(Record::new(label, fields)) } - pub fn symbol>>(s: S) -> Self { + pub fn symbol>>(s: S) -> Self { Shell::Atom(Atom::symbol(s)) } @@ -176,21 +206,21 @@ impl<'a, D: Domain> Shell<'a, D> { } } -impl ValueReader for Shell<'_, D> { - type Impl<'de> = Shell<'de, D>; +impl<'de, D: Domain<'de>> ValueReader<'de> for Shell<'de, D> { + type Impl = Shell<'de, D>; - fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, as ValueImpl>::Embedded>>( + fn read_impl + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, - ) -> Result, ReadError> { + ) -> Result { Ok(read(r, read_annotations, dec)?) } - fn read_iovalue<'de, R: Reader<'de> + ?Sized>( + fn read_iovalue + ?Sized>( r: &mut R, read_annotations: bool, - ) -> Result< as ValueImpl>::IOEmbedded, ReadError> { + ) -> Result<>::IOEmbedded, ReadError> { Ok(Shell::<'de, IOValue>::read_impl( r, read_annotations, @@ -198,13 +228,21 @@ impl ValueReader for Shell<'_, D> { } } -impl<'a, D: Domain> ValueImpl for Shell<'a, D> { - type Handle = ShellHandle<'a, D>; +impl<'de, Err: Into, D: Domain<'de> + FromStr> FromStr for Shell<'de, D> { + type Err = io::Error; + + fn from_str(s: &str) -> Result { + Ok(Shell::read_impl(&mut BytesBinarySource::new(s.as_bytes()).text(), true, &mut DefaultDomainCodec)?) + } +} + +impl<'de, D: Domain<'de>> ValueImpl<'de> for Shell<'de, D> { + type Handle = ShellHandle<'de, D>; type Embedded = D; - type Mapped = Shell<'a, E>; + type Mapped> = Shell<'de, E>; type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i; type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i; - type IOEmbedded = IOValue<'a>; + type IOEmbedded = IOValue<'de>; fn wrap(self) -> Self::Handle { Self::Handle::new(self) @@ -289,7 +327,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { } } - fn copy(w: &E::Handle, f: &mut F) -> Result + fn copy, F, Err>(w: &E::Handle, f: &mut F) -> Result where F: FnMut(&E::Embedded) -> Result { @@ -331,12 +369,12 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { } } - fn map_embedded(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl>::Handle, Err> + fn map_embedded, F, Err>(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl<'de>>::Handle, Err> where F: FnMut(&D) -> Result { Self::Mapped::::copy::(v, &mut |d| Ok( - ShellHandle::<'a, E>::new(Self::Mapped::::Embedded(f(d)?)))) + ShellHandle::<'de, E>::new(Self::Mapped::::Embedded(f(d)?)))) } fn as_boolean(&self) -> Option { @@ -434,7 +472,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { matches!(self, Shell::Set(_)) } - fn has>(&self, v: &E::Handle) -> bool { + fn has>(&self, v: &E::Handle) -> bool { match self { Shell::Set(items) => todo!(), // items.contains(v), _ => false, @@ -445,7 +483,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { matches!(self, Shell::Dictionary(_)) } - fn get>(&self, k: &K::Handle) -> Option { + fn get>(&self, k: &K::Handle) -> Option { match self { Shell::Dictionary(entries) => todo!(), // entries.get(k), _ => None, @@ -466,7 +504,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { } } - fn annotations(&self) -> Option as ValueImpl>::Handle]>> { + fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>> { match self { Shell::Annotated(b) => Some(Cow::Borrowed(&b.0.as_ref().1)), _ => None, @@ -481,34 +519,34 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> { } } -impl_value_methods!({'a, D: Domain}, Shell<'a, D>); +impl_value_methods!({'de, D: Domain<'de>}, Shell<'de, D>); -impl<'a, W: Into>, D: Domain> From for Shell<'a, D> { +impl<'de, W: Into>, D: Domain<'de>> From for Shell<'de, D> { fn from(w: W) -> Self { Shell::Atom(w.into()) } } -impl<'a, D: Domain> From>> for Shell<'a, D> { - fn from(vs: Vec>) -> Self { +impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { + fn from(vs: Vec>) -> Self { Shell::Sequence(vs) } } -impl<'a, D: Domain> From>> for Shell<'a, D> { - fn from(vs: Vec>) -> Self { +impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { + fn from(vs: Vec>) -> Self { vs.iter().map(|v| v.wrap()).collect::>().into() } } -impl<'a, D: Domain> From>> for Shell<'a, D> { - fn from(vs: Set>) -> Self { +impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { + fn from(vs: Set>) -> Self { Shell::Set(vs) } } -impl<'a, D: Domain> From, ShellHandle<'a, D>>> for Shell<'a, D> { - fn from(vs: Map, ShellHandle<'a, D>>) -> Self { +impl<'de, D: Domain<'de>> From, ShellHandle<'de, D>>> for Shell<'de, D> { + fn from(vs: Map, ShellHandle<'de, D>>) -> Self { Shell::Dictionary(vs) } } @@ -534,88 +572,103 @@ impl Record { } #[derive(Clone)] -pub struct Annotations(Box<(V::Handle, Vec< as ValueImpl>::Handle>)>); +pub struct Annotations<'de, V: ValueImpl<'de>>(Box<(V::Handle, Vec< as ValueImpl<'de>>::Handle>)>); -impl Annotations { - pub fn new(v: V::Handle, anns: Vec< as ValueImpl>::Handle>) -> Self { +impl<'de, V: ValueImpl<'de>> Annotations<'de, V> { + pub fn new(v: V::Handle, anns: Vec< as ValueImpl<'de>>::Handle>) -> Self { Self(Box::new((v, anns))) } } -impl Hash for Annotations { +impl<'de, V: ValueImpl<'de>> Hash for Annotations<'de, V> { fn hash(&self, state: &mut H) { self.0.as_ref().0.hash(state) } } -impl PartialEq for Annotations { +impl<'de, V: ValueImpl<'de>> PartialEq for Annotations<'de, V> { fn eq(&self, other: &Self) -> bool { self.0.as_ref().0.eq(&other.0.as_ref().0) } } -impl Ord for Annotations { +impl<'de, V: ValueImpl<'de>> Ord for Annotations<'de, V> { fn cmp(&self, other: &Self) -> Ordering { self.0.as_ref().0.cmp(&other.0.as_ref().0) } } -impl Eq for Annotations {} +impl<'de, V: ValueImpl<'de>> Eq for Annotations<'de, V> {} -impl PartialOrd for Annotations { +impl<'de, V: ValueImpl<'de>> PartialOrd for Annotations<'de, V> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -pub fn copy_iovalue(v: & as ValueImpl>::Handle) -> IOValue { +pub fn copy_iovalue<'de, V: ValueImpl<'de>>(v: & as ValueImpl<'de>>::Handle) -> IOValue<'de> { Shell::copy::, _, _>(v, &mut |a| Result::<_, ()>::Ok( copy_iovalue::(a.as_ref()).into())).unwrap().into() } pub type IOValueImpl<'a> = Shell<'a, IOValue<'a>>; +pub type IOValueIso<'a> = ShellHandle<'a, IOValue<'a>>; #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] -pub struct IOValue<'a>(ShellHandle<'a, IOValue<'a>>); -unsafe impl<'a> TransparentWrapper>> for IOValue<'a> {} +pub struct IOValue<'a>(IOValueIso<'a>); +unsafe impl<'a> TransparentWrapper> for IOValue<'a> {} -impl Domain for IOValue<'_> { - type Decode = IOValueDomainDecode; - type Encode = IOValueDomainEncode; +impl<'de> Domain<'de> for IOValue<'de> { + type Decode = IOValueDomainDecode<'de, IOValueImpl<'de>>; + type Encode = IOValueDomainEncode<'de, Self>; } -impl<'a> Debug for IOValue<'a> { +impl<'de> Debug for IOValue<'de> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { IOValue::peel_ref(self).fmt(f) } } -impl<'a> IOValue<'a> { - pub fn value(&self) -> &IOValueImpl<'a> { +impl<'de> IOValue<'de> { + pub fn record(label: IOValue<'de>, fields: Vec>) -> Self { + IOValue(Shell::Record(Record::new( + label.into(), + fields.into_iter().map(|f| f.into()).collect())).wrap()) + } + + pub fn value(&self) -> &IOValueImpl<'de> { self.0.as_ref() } + + pub fn iso(self) -> IOValueIso<'de> { + IOValue::peel(self) + } } -impl<'a, T: Into>> From for IOValue<'a> { +pub fn iso_parse<'a>(s: &'a str) -> io::Result> { + Ok(IOValue::from_str(s)?.iso()) +} + +impl<'de, T: Into>> From for IOValue<'de> { fn from(t: T) -> Self { IOValue(t.into().wrap()) } } -impl<'a> Borrow> for IOValue<'a> { - fn borrow(&self) -> &IOValueImpl<'a> { +impl<'de> Borrow> for IOValue<'de> { + fn borrow(&self) -> &IOValueImpl<'de> { self.0.as_ref() } } -impl<'a> AsRef>>> for IOValue<'a> { - fn as_ref(&self) -> &Arc>> { +impl<'de> AsRef>>> for IOValue<'de> { + fn as_ref(&self) -> &Arc>> { &self.0 } } -impl<'a> FromStr for IOValue<'a> { +impl<'de> FromStr for IOValue<'de> { type Err = io::Error; fn from_str(s: &str) -> Result { @@ -623,53 +676,53 @@ impl<'a> FromStr for IOValue<'a> { } } -impl<'a> From< as ValueImpl>::Handle> for IOValue<'a> { - fn from(h: as ValueImpl>::Handle) -> Self { +impl<'de> From< as ValueImpl<'de>>::Handle> for IOValue<'de> { + fn from(h: as ValueImpl<'de>>::Handle) -> Self { TransparentWrapper::wrap(h) } } -impl<'r, 'a> From<&'r as ValueImpl>::Handle> for &'r IOValue<'a> { - fn from(h: &'r as ValueImpl>::Handle) -> Self { +impl<'r, 'de> From<&'r as ValueImpl<'de>>::Handle> for &'r IOValue<'de> { + fn from(h: &'r as ValueImpl<'de>>::Handle) -> Self { TransparentWrapper::wrap_ref(h) } } -impl<'a> From> for as ValueImpl>::Handle { - fn from(i: IOValue<'a>) -> Self { +impl<'de> From> for as ValueImpl<'de>>::Handle { + fn from(i: IOValue<'de>) -> Self { IOValue::peel(i) } } -impl<'r, 'a> From<&'r IOValue<'a>> for &'r as ValueImpl>::Handle { - fn from(i: &'r IOValue<'a>) -> Self { +impl<'r, 'de> From<&'r IOValue<'de>> for &'r as ValueImpl<'de>>::Handle { + fn from(i: &'r IOValue<'de>) -> Self { IOValue::peel_ref(i) } } -impl<'a> ValueReader for IOValue<'a> { - type Impl<'i> = IOValue<'i>; +impl<'de> ValueReader<'de> for IOValue<'de> { + type Impl = Self; - fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, as ValueImpl>::Embedded>>( + fn read_impl + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, - ) -> Result, ReadError> { + ) -> Result { Ok(read(r, read_annotations, dec)?.into()) } - fn read_iovalue<'de, R: Reader<'de> + ?Sized>( + fn read_iovalue + ?Sized>( r: &mut R, read_annotations: bool, - ) -> Result< as ValueImpl>::IOEmbedded, ReadError> { - Self::read(r, read_annotations, &mut IOValueDomainDecode::::default()) + ) -> Result<>::IOEmbedded, ReadError> { + Self::read_domain(r, read_annotations, &mut IOValueDomainDecode::::default()) } } -impl<'a> ValueImpl for IOValue<'a> { +impl<'de> ValueImpl<'de> for IOValue<'de> { type Handle = Self; type Embedded = Self; - type Mapped = Shell<'a, E>; + type Mapped> = Shell<'de, E>; type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i; type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i; type IOEmbedded = Self; @@ -738,7 +791,7 @@ impl<'a> ValueImpl for IOValue<'a> { self.value().is_set() } - fn has>(&self, v: &E::Handle) -> bool { + fn has>(&self, v: &E::Handle) -> bool { self.value().has::(v) } @@ -746,7 +799,7 @@ impl<'a> ValueImpl for IOValue<'a> { self.value().is_dictionary() } - fn get>(&self, k: &K::Handle) -> Option { + fn get>(&self, k: &K::Handle) -> Option { self.value().get::(k).map(|v| v.into()) } @@ -758,7 +811,7 @@ impl<'a> ValueImpl for IOValue<'a> { self.value().as_embedded() } - fn annotations(&self) -> Option as ValueImpl>::Handle]>> { + fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>> { self.value().annotations() } @@ -766,20 +819,20 @@ impl<'a> ValueImpl for IOValue<'a> { TransparentWrapper::wrap(Shell::peeled(IOValue::peel_ref(v))) } - fn copy(w: &E::Handle, f: &mut F) -> Result + fn copy, F, Err>(w: &E::Handle, f: &mut F) -> Result where F: FnMut(&E::Embedded) -> Result { IOValueImpl::copy::(w, &mut |e| f(e).map(|v| v.into())).map(|v| v.into()) } - fn map_embedded(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl>::Handle, Err> + fn map_embedded, F, Err>(v: &Self::Handle, f: &mut F) -> Result< as ValueImpl<'de>>::Handle, Err> where F: FnMut(&Self::Embedded) -> Result { IOValueImpl::map_embedded(v.into(), f) } } -pub fn read<'de, R: Reader<'de> + ?Sized, D: Domain, Dec: DomainDecode<'de, D>>( +pub fn read<'de, R: Reader<'de> + ?Sized, D: Domain<'de>, Dec: DomainDecode<'de, D>>( r: &mut R, read_annotations: bool, dec: &mut Dec, diff --git a/implementations/rust/preserves/src/text/mod.rs b/implementations/rust/preserves/src/text/mod.rs index 411efe1..657c631 100644 --- a/implementations/rust/preserves/src/text/mod.rs +++ b/implementations/rust/preserves/src/text/mod.rs @@ -14,33 +14,32 @@ use crate::Shell; use crate::ShellHandle; use crate::ValueReader; -pub fn from_str<'de, D: Domain, Dec: DomainDecode<'de, D>>( +pub fn from_str<'de, D: Domain<'de>, Dec: DomainDecode<'de, D>>( s: &'de str, decode_embedded: &mut Dec, ) -> io::Result> { - Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), false, decode_embedded)?) + Ok(Shell::read_domain(&mut BytesBinarySource::new(s.as_bytes()).text(), false, decode_embedded)?) } -pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode<'de, D>>( +pub fn annotated_from_str<'de, D: Domain<'de>, Dec: DomainDecode<'de, D>>( s: &'de str, decode_embedded: &mut Dec, ) -> io::Result> { - Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), true, decode_embedded)?) + Ok(Shell::read_domain(&mut BytesBinarySource::new(s.as_bytes()).text(), true, decode_embedded)?) } #[cfg(test)] mod formatting_tests { - use crate::IOValue; + use crate::{IOValue, Shell, ValueImpl}; use crate::test_domain::Dom; - use crate::ArcValue; #[test] fn format_debug_and_parse() { - let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::>().unwrap(); + let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::>().unwrap().wrap(); assert_eq!(format!("{:?}", &v), "[1, {a: #!\"One\", z: 2}, 3]"); } #[test] fn format_pretty_debug_and_parse() { - let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::>().unwrap(); + let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::>().unwrap().wrap(); assert_eq!(format!("{:#?}", &v), concat!( "[\n", " 1,\n", @@ -76,7 +75,7 @@ mod unusual_float_tests { fn d32(u: u32, expected: &str) { let v = f32::from_bits(u); - let w = iovalue(v); + let w: IOValue = v.into(); assert_eq!(format!("{:?}", w), expected); let x = expected.parse::().unwrap(); assert_eq!(x, w); @@ -84,7 +83,7 @@ mod unusual_float_tests { fn d64(u: u64, expected: &str) { let v = f64::from_bits(u); - let w = iovalue(v); + let w: IOValue = v.into(); assert_eq!(format!("{:?}", w), expected); let x = expected.parse::().unwrap(); assert_eq!(x, w); diff --git a/implementations/rust/preserves/src/text/writer.rs b/implementations/rust/preserves/src/text/writer.rs index ee06f59..59b19d0 100644 --- a/implementations/rust/preserves/src/text/writer.rs +++ b/implementations/rust/preserves/src/text/writer.rs @@ -33,7 +33,7 @@ impl std::default::Default for CommaStyle { } impl TextWriter<&mut Vec> { - pub fn fmt_value>( + pub fn fmt_value<'de, V: ValueImpl<'de>, Enc: DomainEncode<'de, V::Embedded>>( f: &mut std::fmt::Formatter<'_>, enc: &mut Enc, v: &V, @@ -46,7 +46,7 @@ impl TextWriter<&mut Vec> { |_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter")) } - pub fn encode>( + pub fn encode<'de, V: ValueImpl<'de>, Enc: DomainEncode<'de, V::Embedded>>( enc: &mut Enc, v: &V, ) -> io::Result { diff --git a/implementations/rust/preserves/src/writer.rs b/implementations/rust/preserves/src/writer.rs index 7b9502a..1282f4f 100644 --- a/implementations/rust/preserves/src/writer.rs +++ b/implementations/rust/preserves/src/writer.rs @@ -70,10 +70,10 @@ pub trait Writer { fn specialized(&mut self) -> Option<(&str, &mut dyn io::Write)> { None } } -pub fn write_value( +pub fn write_value<'de, V: ValueImpl<'de>>( w: &mut dyn Writer, v: &V, - enc: &mut dyn DomainEncode, + enc: &mut dyn DomainEncode<'de, V::Embedded>, ) -> io::Result<()> { let annotations = v.annotations(); let mut annotation_b = B::Type::default();