Good progress

This commit is contained in:
Tony Garnock-Jones 2022-11-20 21:54:09 +01:00
parent 025c5bb962
commit 1f7895e14e
11 changed files with 312 additions and 237 deletions

View File

@ -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<Self> + 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<R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
@ -16,7 +16,7 @@ pub trait DomainDecode<'de, D: Domain> {
) -> io::Result<D>;
}
pub trait DomainEncode<D: Domain> {
pub trait DomainEncode<'de, D: Domain<'de>> {
fn encode_embedded(
&mut self,
w: &mut dyn Writer,
@ -24,7 +24,7 @@ pub trait DomainEncode<D: Domain> {
) -> 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<R: Reader<'de> + ?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<D>> DomainEncode<D> 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<D>> DomainEncode<D> 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<R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
@ -57,7 +57,7 @@ impl<'de, D: Domain> DomainDecode<'de, D> for DefaultDomainCodec {
}
}
impl<D: Domain> DomainEncode<D> 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<D: Domain> DomainEncode<D> for DefaultDomainCodec {
#[derive(Default)]
pub struct DebugDomainCodec;
impl<'de, Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<'de, D> for DebugDomainCodec {
impl<'de, Err: Into<io::Error>, D: Domain<'de> + std::str::FromStr<Err = Err>> DomainDecode<'de, D> for DebugDomainCodec {
fn decode_embedded<R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
@ -80,7 +80,7 @@ impl<'de, Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> Domain
}
}
impl<D: Domain> DomainEncode<D> 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<D: Domain> DomainEncode<D> 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<R: Reader<'de> + ?Sized>(
&mut self,
_r: &mut R,
@ -103,7 +103,7 @@ impl<'de, D: Domain> DomainDecode<'de, D> for NoEmbeddedDomainCodec {
}
}
impl<D: Domain> DomainEncode<D> for NoEmbeddedDomainCodec {
impl<'de, D: Domain<'de>> DomainEncode<'de, D> for NoEmbeddedDomainCodec {
fn encode_embedded(
&mut self,
_w: &mut dyn Writer,

View File

@ -9,23 +9,23 @@ use crate::ValueImpl;
use crate::Writer;
use crate::ValueReader;
pub struct IOValueDomainDecode<V: ValueReader>(PhantomData<V>);
pub struct IOValueDomainEncode<V: ValueImpl>(PhantomData<V>);
pub struct IOValueDomainDecode<'de, V: ValueReader<'de>>(PhantomData<&'de V>);
pub struct IOValueDomainEncode<'de, V: ValueImpl<'de>>(PhantomData<&'de V>);
impl<V: ValueReader> Default for IOValueDomainDecode<V> { fn default() -> Self { Self(PhantomData) } }
impl<V: ValueImpl> Default for IOValueDomainEncode<V> { 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, <V::Impl<'de> as ValueImpl>::IOEmbedded> for IOValueDomainDecode<V> {
impl<'de, V: ValueReader<'de>> DomainDecode<'de, <V::Impl as ValueImpl<'de>>::IOEmbedded> for IOValueDomainDecode<'de, V> {
fn decode_embedded<R: Reader<'de> + ?Sized>(
&mut self,
r: &mut R,
read_annotations: bool,
) -> io::Result<<V::Impl<'de> as ValueImpl>::IOEmbedded> {
) -> io::Result<<V::Impl as ValueImpl<'de>>::IOEmbedded> {
Ok(V::read_iovalue(r, read_annotations)?)
}
}
impl<V: ValueImpl> DomainEncode<V::IOEmbedded> for IOValueDomainEncode<V> {
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<V: ValueImpl> DomainEncode<V::IOEmbedded> for IOValueDomainEncode<V> {
}
}
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<<V::Impl<'de> as ValueImpl>::IOEmbedded>;
impl<'de, V: ValueReader<'de>, R: Reader<'de>> Iterator for IOValues<'de, V, R> {
type Item = io::Result<<V::Impl as ValueImpl<'de>>::IOEmbedded>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.peek_class() {

View File

@ -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<NoValue> = "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<NoValue>, PlainValue<NoValue>> = 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), "<foo bar zot>".parse().unwrap());
// let w: &dyn ValueImpl<NoValue> = &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<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.unwrap();
// // let key = line.parse::<PlainValue<NoValue>>().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::<PlainValue<NoValue>>()?;
// 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>>>());
// }
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)]
@ -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<Dom> for DomCodec {
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
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 = 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<Dom> 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::<Shell::<Dom>, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(),
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]);
}
@ -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::<Shell::<Dom>, _, _>(&v, &mut dom_as_preserves).unwrap()).unwrap(),
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]);
}
}

View File

@ -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<ShellHandle<'de, D>> {
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<ShellHandle<'de, D>> {
Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?)
Ok(Shell::read_domain(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?)
}

View File

@ -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<IndexedRepr<'de, D>>,
annotation_offset: usize,
value_range: Range<usize>,
@ -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<IndexInProgress<'dec, D, Dec>>,
@ -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<usize>) -> Arc<IndexedRepr<'static, D>> {
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<Dec: DomainDecode<'de, D>>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>) -> io::Result<Self> {
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<Dec: DomainDecode<'de, D>>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>, offset: usize) -> io::Result<Self> {
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<E: Domain> = View<'de, E>;
type Mapped<E: Domain<'de>> = View<'de, E>;
type Items<'a> = ViewIterator<IndexedRepr<'de, D>> where Self: 'a;
type Entries<'a> = DictionaryAdapter<IndexedRepr<'de, D>> 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<D>) -> io::Result<()> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> 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<E: ValueImpl<Embedded = Self::Embedded>>(&self, v: &E::Handle) -> bool {
fn has<E: ValueImpl<'de, Embedded = Self::Embedded>>(&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<K: ValueImpl<Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
fn get<K: ValueImpl<'de, Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
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<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> 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<E: ValueImpl, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
fn copy<E: ValueImpl<'de>, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
where
F: FnMut(&E::Embedded) -> Result<Self::Handle, Err> {
todo!()
}
fn map_embedded<E: Domain, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl>::Handle, Err>
fn map_embedded<E: Domain<'de>, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl<'de>>::Handle, Err>
where
F: FnMut(&Self::Embedded) -> Result<E, Err> {
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<IOViewImpl<'de>> for IOView<'de> {
}
}
pub struct ViewStream<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D> = <D as Domain>::Decode> {
pub struct ViewStream<'de, 'dec, D: Domain<'de>, Dec: DomainDecode<'de, D> = <D as Domain<'de>>::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<View<'de, D>>;
fn next(&mut self) -> Option<Self::Item> {
@ -632,13 +635,13 @@ pub struct ViewIterator<Repr> {
offset: usize,
}
impl<'de, D: Domain> ViewIterator<IndexedRepr<'de, D>> {
impl<'de, D: Domain<'de>> ViewIterator<IndexedRepr<'de, D>> {
pub fn inner_new(repr: &Arc<IndexedRepr<'de, D>>, offset: usize) -> Self {
ViewIterator { repr: Arc::clone(repr), offset }
}
}
impl<'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, D>> {
impl<'de, D: Domain<'de>> Iterator for ViewIterator<IndexedRepr<'de, D>> {
type Item = View<'de, D>;
fn next(&mut self) -> Option<Self::Item> {
@ -654,7 +657,7 @@ impl<'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, D>> {
pub struct DictionaryAdapter<Repr>(pub ViewIterator<Repr>);
impl<'de, D: Domain> Iterator for DictionaryAdapter<IndexedRepr<'de, D>> {
impl<'de, D: Domain<'de>> Iterator for DictionaryAdapter<IndexedRepr<'de, D>> {
type Item = (View<'de, D>, View<'de, D>);
fn next(&mut self) -> Option<Self::Item> {

View File

@ -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<W: io::Write> {
base: W,
@ -36,7 +36,7 @@ pub struct PackedWriter<W: io::Write>(Buffers<W>);
impl PackedWriter<&mut Vec<u8>> {
#[inline(always)]
pub fn encode<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
pub fn encode_domain<'de, V: ValueImpl<'de>, Enc: DomainEncode<'de, V::Embedded>>(
enc: &mut Enc,
v: &V,
) -> io::Result<Vec<u8>> {
@ -44,6 +44,11 @@ impl PackedWriter<&mut Vec<u8>> {
v.write(&mut PackedWriter::new(&mut buf), enc)?;
Ok(buf)
}
#[inline(always)]
pub fn encode<'de, V: ValueImpl<'de>>(v: &V) -> io::Result<Vec<u8>> {
Self::encode_domain(&mut DefaultDomainCodec, v)
}
}
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {

View File

@ -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<<Self::Impl<'de> as ValueImpl>::Embedded>>(
fn read_impl<R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl as ValueImpl<'de>>::Embedded>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> Result<Self::Impl<'de>, ReadError>;
) -> Result<Self::Impl, ReadError>;
fn read<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<<Self::Impl<'de> as ValueImpl>::Embedded>>(
fn read_domain<R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl as ValueImpl<'de>>::Embedded>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> Result<<Self::Impl<'de> as ValueImpl>::Handle, ReadError> {
) -> Result<<Self::Impl as ValueImpl<'de>>::Handle, ReadError> {
Ok(Self::read_impl(r, read_annotations, dec)?.wrap())
}
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
fn read<R: Reader<'de> + ?Sized>(
r: &mut R,
read_annotations: bool,
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError>;
) -> Result<<Self::Impl as ValueImpl<'de>>::Handle, ReadError> {
Self::read_domain(r, read_annotations, &mut DefaultDomainCodec)
}
fn gather_annotations<'de, R: Reader<'de> + ?Sized>(
fn read_iovalue<R: Reader<'de> + ?Sized>(
r: &mut R,
) -> io::Result<Option<(Vec<<<Self::Impl<'de> as ValueImpl>::Mapped<<Self::Impl<'de> as ValueImpl>::IOEmbedded> as ValueImpl>::Handle>, ValueClass)>> {
read_annotations: bool,
) -> Result<<Self::Impl as ValueImpl<'de>>::IOEmbedded, ReadError>;
fn gather_annotations<R: Reader<'de> + ?Sized>(
r: &mut R,
) -> io::Result<Option<(Vec<<<Self::Impl as ValueImpl<'de>>::Mapped<<Self::Impl as ValueImpl<'de>>::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<Self> + Clone + From<Self> + Hash + Eq + Ord + PartialEq + PartialOrd;
type Embedded: Domain;
type Mapped<E: Domain>: ValueImpl<Embedded = E>;
type Embedded: Domain<'de>;
type Mapped<E: Domain<'de>>: ValueImpl<'de, Embedded = E>;
type Items<'a>: Iterator<Item = Self::Handle> + 'a where Self: 'a;
type Entries<'a>: Iterator<Item = (Self::Handle, Self::Handle)> + 'a where Self: 'a;
type IOEmbedded: From<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
Into<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
AsRef<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
Domain;
type IOEmbedded: From<<Self::Mapped<Self::IOEmbedded> as ValueImpl<'de>>::Handle> +
Into<<Self::Mapped<Self::IOEmbedded> as ValueImpl<'de>>::Handle> +
AsRef<<Self::Mapped<Self::IOEmbedded> 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<E: ValueImpl<Embedded = Self::Embedded>>(&self, _v: &E::Handle) -> bool;
fn has<E: ValueImpl<'de, Embedded = Self::Embedded>>(&self, _v: &E::Handle) -> bool;
fn is_dictionary(&self) -> bool;
fn get<K: ValueImpl<Embedded = Self::Embedded>>(&self, _k: &K::Handle) -> Option<Self::Handle>;
fn get<K: ValueImpl<'de, Embedded = Self::Embedded>>(&self, _k: &K::Handle) -> Option<Self::Handle>;
fn entries(&self) -> Self::Entries<'_>;
fn as_embedded(&self) -> Option<Cow<'_, Self::Embedded>>;
// INVARIANT: return Some() *only* when the contained collection is nonempty
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>>;
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl<'de>>::Handle]>>;
fn peeled(v: &Self::Handle) -> Self::Handle;
fn copy<E: ValueImpl, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
fn copy<E: ValueImpl<'de>, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
where
F: FnMut(&E::Embedded) -> Result<Self::Handle, Err>;
fn map_embedded<E: Domain, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl>::Handle, Err>
fn map_embedded<E: Domain<'de>, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl<'de>>::Handle, Err>
where
F: FnMut(&Self::Embedded) -> Result<E, Err>;
}
pub fn value_hash<V: ValueImpl, H: Hasher>(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: ValueImpl, H: Hasher>(v: &V, state: &mut H) {
}
// TODO: when unstable feature iter_order_by stabilises, use that instead
fn iters_eq<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(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<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(i: &V::Items<'_>
}
}
pub fn value_eq<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(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: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(v: &V, w: &W
}
// TODO: when unstable feature iter_order_by stabilises, use that instead
fn iters_cmp<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(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<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(i: &V::Items<'_
}
}
pub fn value_cmp<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(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 {

View File

@ -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<String> 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<Vec<u8>> for Atom<'a> { fn from(v: Vec<u8>) -> Self { Atom::ByteString(Cow::Owned(v)) } }
impl<'a> From<i8> for Atom<'a> { fn from(i: i8) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<u8> for Atom<'a> { fn from(i: u8) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<i16> for Atom<'a> { fn from(i: i16) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<u16> for Atom<'a> { fn from(i: u16) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<i32> for Atom<'a> { fn from(i: i32) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<u32> for Atom<'a> { fn from(i: u32) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<i64> for Atom<'a> { fn from(i: i64) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<u64> for Atom<'a> { fn from(i: u64) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<i128> for Atom<'a> { fn from(i: i128) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<u128> for Atom<'a> { fn from(i: u128) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<isize> for Atom<'a> { fn from(i: isize) -> Self { SignedInteger::from(i).into() } }
impl<'a> From<usize> 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<Self, Self::Error> {
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<Shell<'a, D>>;
pub enum Shell<'a, D: Domain> {
Atom(Atom<'a>),
Record(Record<ShellHandle<'a, D>>),
Sequence(Vec<ShellHandle<'a, D>>),
Set(Set<ShellHandle<'a, D>>),
Dictionary(Map<ShellHandle<'a, D>, ShellHandle<'a, D>>),
pub enum Shell<'de, D: Domain<'de>> {
Atom(Atom<'de>),
Record(Record<ShellHandle<'de, D>>),
Sequence(Vec<ShellHandle<'de, D>>),
Set(Set<ShellHandle<'de, D>>),
Dictionary(Map<ShellHandle<'de, D>, ShellHandle<'de, D>>),
Embedded(D),
Annotated(Annotations<Self>),
Annotated(Annotations<'de, Self>),
}
impl<'a, D: Domain> Shell<'a, D> {
pub fn record(label: ShellHandle<'a, D>, fields: Vec<ShellHandle<'a, D>>) -> Self {
impl<'de, D: Domain<'de>> Shell<'de, D> {
pub fn record(label: ShellHandle<'de, D>, fields: Vec<ShellHandle<'de, D>>) -> Self {
Shell::Record(Record::new(label, fields))
}
pub fn symbol<S: Into<Cow<'a, str>>>(s: S) -> Self {
pub fn symbol<S: Into<Cow<'de, str>>>(s: S) -> Self {
Shell::Atom(Atom::symbol(s))
}
@ -176,21 +206,21 @@ impl<'a, D: Domain> Shell<'a, D> {
}
}
impl<D: Domain> 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, <Self::Impl<'de> as ValueImpl>::Embedded>>(
fn read_impl<R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl as ValueImpl<'de>>::Embedded>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> Result<Self::Impl<'de>, ReadError> {
) -> Result<Self::Impl, ReadError> {
Ok(read(r, read_annotations, dec)?)
}
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
fn read_iovalue<R: Reader<'de> + ?Sized>(
r: &mut R,
read_annotations: bool,
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError> {
) -> Result<<Self::Impl as ValueImpl<'de>>::IOEmbedded, ReadError> {
Ok(Shell::<'de, IOValue>::read_impl(
r,
read_annotations,
@ -198,13 +228,21 @@ impl<D: Domain> ValueReader for Shell<'_, D> {
}
}
impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
type Handle = ShellHandle<'a, D>;
impl<'de, Err: Into<io::Error>, D: Domain<'de> + FromStr<Err = Err>> FromStr for Shell<'de, D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
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<E: Domain> = Shell<'a, E>;
type Mapped<E: Domain<'de>> = 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<E: ValueImpl, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
fn copy<E: ValueImpl<'de>, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
where
F: FnMut(&E::Embedded) -> Result<Self::Handle, Err>
{
@ -331,12 +369,12 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
}
}
fn map_embedded<E: Domain, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl>::Handle, Err>
fn map_embedded<E: Domain<'de>, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl<'de>>::Handle, Err>
where
F: FnMut(&D) -> Result<E, Err>
{
Self::Mapped::<E>::copy::<Self, _, _>(v, &mut |d| Ok(
ShellHandle::<'a, E>::new(Self::Mapped::<E>::Embedded(f(d)?))))
ShellHandle::<'de, E>::new(Self::Mapped::<E>::Embedded(f(d)?))))
}
fn as_boolean(&self) -> Option<bool> {
@ -434,7 +472,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
matches!(self, Shell::Set(_))
}
fn has<E: ValueImpl<Embedded = D>>(&self, v: &E::Handle) -> bool {
fn has<E: ValueImpl<'de, Embedded = D>>(&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<K: ValueImpl<Embedded = D>>(&self, k: &K::Handle) -> Option<Self::Handle> {
fn get<K: ValueImpl<'de, Embedded = D>>(&self, k: &K::Handle) -> Option<Self::Handle> {
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<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> 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<Atom<'a>>, D: Domain> From<W> for Shell<'a, D> {
impl<'de, W: Into<Atom<'de>>, D: Domain<'de>> From<W> for Shell<'de, D> {
fn from(w: W) -> Self {
Shell::Atom(w.into())
}
}
impl<'a, D: Domain> From<Vec<ShellHandle<'a, D>>> for Shell<'a, D> {
fn from(vs: Vec<ShellHandle<'a, D>>) -> Self {
impl<'de, D: Domain<'de>> From<Vec<ShellHandle<'de, D>>> for Shell<'de, D> {
fn from(vs: Vec<ShellHandle<'de, D>>) -> Self {
Shell::Sequence(vs)
}
}
impl<'a, D: Domain> From<Vec<Shell<'a, D>>> for Shell<'a, D> {
fn from(vs: Vec<Shell<'a, D>>) -> Self {
impl<'de, D: Domain<'de>> From<Vec<Shell<'de, D>>> for Shell<'de, D> {
fn from(vs: Vec<Shell<'de, D>>) -> Self {
vs.iter().map(|v| v.wrap()).collect::<Vec<_>>().into()
}
}
impl<'a, D: Domain> From<Set<ShellHandle<'a, D>>> for Shell<'a, D> {
fn from(vs: Set<ShellHandle<'a, D>>) -> Self {
impl<'de, D: Domain<'de>> From<Set<ShellHandle<'de, D>>> for Shell<'de, D> {
fn from(vs: Set<ShellHandle<'de, D>>) -> Self {
Shell::Set(vs)
}
}
impl<'a, D: Domain> From<Map<ShellHandle<'a, D>, ShellHandle<'a, D>>> for Shell<'a, D> {
fn from(vs: Map<ShellHandle<'a, D>, ShellHandle<'a, D>>) -> Self {
impl<'de, D: Domain<'de>> From<Map<ShellHandle<'de, D>, ShellHandle<'de, D>>> for Shell<'de, D> {
fn from(vs: Map<ShellHandle<'de, D>, ShellHandle<'de, D>>) -> Self {
Shell::Dictionary(vs)
}
}
@ -534,88 +572,103 @@ impl<V> Record<V> {
}
#[derive(Clone)]
pub struct Annotations<V: ValueImpl>(Box<(V::Handle, Vec<<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle>)>);
pub struct Annotations<'de, V: ValueImpl<'de>>(Box<(V::Handle, Vec<<V::Mapped<V::IOEmbedded> as ValueImpl<'de>>::Handle>)>);
impl<V: ValueImpl> Annotations<V> {
pub fn new(v: V::Handle, anns: Vec<<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle>) -> Self {
impl<'de, V: ValueImpl<'de>> Annotations<'de, V> {
pub fn new(v: V::Handle, anns: Vec<<V::Mapped<V::IOEmbedded> as ValueImpl<'de>>::Handle>) -> Self {
Self(Box::new((v, anns)))
}
}
impl<V: ValueImpl> Hash for Annotations<V> {
impl<'de, V: ValueImpl<'de>> Hash for Annotations<'de, V> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.as_ref().0.hash(state)
}
}
impl<V: ValueImpl> PartialEq for Annotations<V> {
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<V: ValueImpl> Ord for Annotations<V> {
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<V: ValueImpl> Eq for Annotations<V> {}
impl<'de, V: ValueImpl<'de>> Eq for Annotations<'de, V> {}
impl<V: ValueImpl> PartialOrd for Annotations<V> {
impl<'de, V: ValueImpl<'de>> PartialOrd for Annotations<'de, V> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub fn copy_iovalue<V: ValueImpl>(v: &<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle) -> IOValue {
pub fn copy_iovalue<'de, V: ValueImpl<'de>>(v: &<V::Mapped<V::IOEmbedded> as ValueImpl<'de>>::Handle) -> IOValue<'de> {
Shell::copy::<V::Mapped<V::IOEmbedded>, _, _>(v, &mut |a| Result::<_, ()>::Ok(
copy_iovalue::<V>(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<ShellHandle<'a, IOValue<'a>>> for IOValue<'a> {}
pub struct IOValue<'a>(IOValueIso<'a>);
unsafe impl<'a> TransparentWrapper<IOValueIso<'a>> for IOValue<'a> {}
impl Domain for IOValue<'_> {
type Decode = IOValueDomainDecode<Self>;
type Encode = IOValueDomainEncode<Self>;
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<IOValue<'de>>) -> 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<IOValueImpl<'a>>> From<T> for IOValue<'a> {
pub fn iso_parse<'a>(s: &'a str) -> io::Result<IOValueIso<'a>> {
Ok(IOValue::from_str(s)?.iso())
}
impl<'de, T: Into<IOValueImpl<'de>>> From<T> for IOValue<'de> {
fn from(t: T) -> Self {
IOValue(t.into().wrap())
}
}
impl<'a> Borrow<IOValueImpl<'a>> for IOValue<'a> {
fn borrow(&self) -> &IOValueImpl<'a> {
impl<'de> Borrow<IOValueImpl<'de>> for IOValue<'de> {
fn borrow(&self) -> &IOValueImpl<'de> {
self.0.as_ref()
}
}
impl<'a> AsRef<Arc<Shell<'a, IOValue<'a>>>> for IOValue<'a> {
fn as_ref(&self) -> &Arc<Shell<'a, IOValue<'a>>> {
impl<'de> AsRef<Arc<Shell<'de, IOValue<'de>>>> for IOValue<'de> {
fn as_ref(&self) -> &Arc<Shell<'de, IOValue<'de>>> {
&self.0
}
}
impl<'a> FromStr for IOValue<'a> {
impl<'de> FromStr for IOValue<'de> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -623,53 +676,53 @@ impl<'a> FromStr for IOValue<'a> {
}
}
impl<'a> From<<IOValueImpl<'a> as ValueImpl>::Handle> for IOValue<'a> {
fn from(h: <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
impl<'de> From<<IOValueImpl<'de> as ValueImpl<'de>>::Handle> for IOValue<'de> {
fn from(h: <IOValueImpl<'de> as ValueImpl<'de>>::Handle) -> Self {
TransparentWrapper::wrap(h)
}
}
impl<'r, 'a> From<&'r <IOValueImpl<'a> as ValueImpl>::Handle> for &'r IOValue<'a> {
fn from(h: &'r <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
impl<'r, 'de> From<&'r <IOValueImpl<'de> as ValueImpl<'de>>::Handle> for &'r IOValue<'de> {
fn from(h: &'r <IOValueImpl<'de> as ValueImpl<'de>>::Handle) -> Self {
TransparentWrapper::wrap_ref(h)
}
}
impl<'a> From<IOValue<'a>> for <IOValueImpl<'a> as ValueImpl>::Handle {
fn from(i: IOValue<'a>) -> Self {
impl<'de> From<IOValue<'de>> for <IOValueImpl<'de> as ValueImpl<'de>>::Handle {
fn from(i: IOValue<'de>) -> Self {
IOValue::peel(i)
}
}
impl<'r, 'a> From<&'r IOValue<'a>> for &'r <IOValueImpl<'a> as ValueImpl>::Handle {
fn from(i: &'r IOValue<'a>) -> Self {
impl<'r, 'de> From<&'r IOValue<'de>> for &'r <IOValueImpl<'de> 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, <Self::Impl<'de> as ValueImpl>::Embedded>>(
fn read_impl<R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl as ValueImpl<'de>>::Embedded>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> Result<Self::Impl<'de>, ReadError> {
) -> Result<Self::Impl, ReadError> {
Ok(read(r, read_annotations, dec)?.into())
}
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
fn read_iovalue<R: Reader<'de> + ?Sized>(
r: &mut R,
read_annotations: bool,
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError> {
Self::read(r, read_annotations, &mut IOValueDomainDecode::<Self>::default())
) -> Result<<Self::Impl as ValueImpl<'de>>::IOEmbedded, ReadError> {
Self::read_domain(r, read_annotations, &mut IOValueDomainDecode::<Self>::default())
}
}
impl<'a> ValueImpl for IOValue<'a> {
impl<'de> ValueImpl<'de> for IOValue<'de> {
type Handle = Self;
type Embedded = Self;
type Mapped<E: Domain> = Shell<'a, E>;
type Mapped<E: Domain<'de>> = 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<E: ValueImpl<Embedded = Self::Embedded>>(&self, v: &E::Handle) -> bool {
fn has<E: ValueImpl<'de, Embedded = Self::Embedded>>(&self, v: &E::Handle) -> bool {
self.value().has::<E>(v)
}
@ -746,7 +799,7 @@ impl<'a> ValueImpl for IOValue<'a> {
self.value().is_dictionary()
}
fn get<K: ValueImpl<Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
fn get<K: ValueImpl<'de, Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
self.value().get::<K>(k).map(|v| v.into())
}
@ -758,7 +811,7 @@ impl<'a> ValueImpl for IOValue<'a> {
self.value().as_embedded()
}
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> 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<E: ValueImpl, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
fn copy<E: ValueImpl<'de>, F, Err>(w: &E::Handle, f: &mut F) -> Result<Self::Handle, Err>
where
F: FnMut(&E::Embedded) -> Result<Self::Handle, Err> {
IOValueImpl::copy::<E, _, _>(w, &mut |e| f(e).map(|v| v.into())).map(|v| v.into())
}
fn map_embedded<E: Domain, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl>::Handle, Err>
fn map_embedded<E: Domain<'de>, F, Err>(v: &Self::Handle, f: &mut F) -> Result<<Self::Mapped<E> as ValueImpl<'de>>::Handle, Err>
where
F: FnMut(&Self::Embedded) -> Result<E, Err> {
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,

View File

@ -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<ShellHandle<'de, D>> {
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<ShellHandle<'de, D>> {
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::<ArcValue<Dom>>().unwrap();
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<Shell<Dom>>().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::<ArcValue<Dom>>().unwrap();
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<Shell<Dom>>().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::<IOValue>().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::<IOValue>().unwrap();
assert_eq!(x, w);

View File

@ -33,7 +33,7 @@ impl std::default::Default for CommaStyle {
}
impl TextWriter<&mut Vec<u8>> {
pub fn fmt_value<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
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<u8>> {
|_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter"))
}
pub fn encode<V: ValueImpl, Enc: DomainEncode<V::Embedded>>(
pub fn encode<'de, V: ValueImpl<'de>, Enc: DomainEncode<'de, V::Embedded>>(
enc: &mut Enc,
v: &V,
) -> io::Result<String> {

View File

@ -70,10 +70,10 @@ pub trait Writer {
fn specialized(&mut self) -> Option<(&str, &mut dyn io::Write)> { None }
}
pub fn write_value<V: ValueImpl>(
pub fn write_value<'de, V: ValueImpl<'de>>(
w: &mut dyn Writer,
v: &V,
enc: &mut dyn DomainEncode<V::Embedded>,
enc: &mut dyn DomainEncode<'de, V::Embedded>,
) -> io::Result<()> {
let annotations = v.annotations();
let mut annotation_b = B::Type::default();