use std::borrow::Borrow; use std::borrow::Cow; use std::cmp::Ordering; use std::fmt::Debug; use std::hash::Hash; use std::hash::Hasher; use std::io; use std::str::FromStr; 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; 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; pub use std::collections::BTreeSet as Set; pub use std::collections::BTreeMap as Map; #[derive(Debug, Clone)] pub enum Atom<'a> { Boolean(bool), Float(f32), Double(f64), SignedInteger(Cow<'a, SignedInteger>), String(Cow<'a, str>), ByteString(Cow<'a, [u8]>), Symbol(Cow<'a, str>), } impl<'a> Atom<'a> { pub fn into_owned(self) -> Atom<'static> { match self { Atom::Boolean(b) => Atom::Boolean(b), Atom::Float(f) => Atom::Float(f), Atom::Double(d) => Atom::Double(d), Atom::SignedInteger(i) => Atom::SignedInteger(i.to_owned()), Atom::String(s) => Atom::String(s.to_owned()), Atom::ByteString(bs) => Atom::ByteString(bs.to_owned()), Atom::Symbol(s) => Atom::Symbol(s.to_owned()), } } pub fn write(&self, w: &mut dyn Writer) -> io::Result<()> { match self { Atom::Boolean(b) => w.write_bool(*b), Atom::Float(f) => w.write_f32(*f), Atom::Double(d) => w.write_f64(*d), Atom::SignedInteger(i) => w.write_signed_integer(i), Atom::String(s) => w.write_string(s), Atom::ByteString(bs) => w.write_bytes(bs), Atom::Symbol(s) => w.write_symbol(s), } } pub fn symbol>>(v: W) -> Self { Atom::Symbol(v.into()) } pub fn try_into_symbol(self) -> Result, ExpectedKind> { match self { Atom::Symbol(s) => Ok(s), _ => Err(ExpectedKind::Symbol), } } pub fn as_symbol(self) -> Result<&'a str, ExpectedKind> { match self { Atom::Symbol(s) => Ok(s.as_ref()), _ => Err(ExpectedKind::Symbol), } } } impl<'r, 'a> From<&'r Atom<'a>> for AtomClass { fn from(a: &'r Atom<'a>) -> Self { match a { Atom::Boolean(_) => AtomClass::Boolean, Atom::Float(_) => AtomClass::Float, Atom::Double(_) => AtomClass::Double, Atom::SignedInteger(_) => AtomClass::SignedInteger, Atom::String(_) => AtomClass::String, Atom::ByteString(_) => AtomClass::ByteString, Atom::Symbol(_) => AtomClass::Symbol, } } } impl<'a> From for Atom<'a> { fn from(v: bool) -> Self { Atom::Boolean(v) } } impl<'a> From for Atom<'a> { fn from(v: f32) -> Self { Atom::Float(v) } } impl<'a> From for Atom<'a> { fn from(v: f64) -> Self { Atom::Double(v) } } impl<'a> From<&'a SignedInteger> for Atom<'a> { fn from(v: &'a SignedInteger) -> Self { Atom::SignedInteger(Cow::Borrowed(v)) } } impl<'a> From for Atom<'a> { fn from(v: SignedInteger) -> Self { Atom::SignedInteger(Cow::Owned(v)) } } impl<'a> From<&'a str> for Atom<'a> { fn from(v: &'a str) -> Self { Atom::String(Cow::Borrowed(v)) } } impl<'a> From for Atom<'a> { fn from(v: String) -> Self { Atom::String(Cow::Owned(v)) } } 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, $errty:ty, $err:expr) => { impl<'r, 'a> TryFrom<&'r Atom<'a>> for $t { type Error = $errty; fn try_from(value: &'r Atom<'a>) -> Result { match value { $p => Ok($e), _ => Err($err), } } } }; } 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) => { impl<'a> TryFrom> for $t { type Error = ExpectedKind; fn try_from(value: Atom<'a>) -> Result { match value { $p => Ok($e), _ => Err($err), } } } }; } from_atom_val_impl!(bool, Atom::Boolean(b), b, ExpectedKind::Boolean); from_atom_val_impl!(f32, Atom::Float(f), f, ExpectedKind::Float); from_atom_val_impl!(f64, Atom::Double(d), d, ExpectedKind::Double); from_atom_val_impl!(Cow<'a, SignedInteger>, Atom::SignedInteger(i), i, ExpectedKind::SignedInteger); 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<'de, D: Domain<'de>> { Atom(Atom<'de>), Record(Record>), Sequence(Vec>), Set(Set>), Dictionary(Map, ShellHandle<'de, D>>), Embedded(D), Annotated(Annotations<'de, 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 { Shell::Atom(Atom::symbol(s)) } pub fn embedded(d: D) -> Self { Shell::Embedded(d) } } impl<'de, D: Domain<'de>> ValueReader<'de> for Shell<'de, D> { type Impl = Shell<'de, D>; fn read_impl + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, ) -> Result { Ok(read(r, read_annotations, dec)?) } fn read_iovalue + ?Sized>( r: &mut R, read_annotations: bool, ) -> Result<>::IOEmbedded, ReadError> { Ok(Shell::<'de, IOValue>::read_impl( r, read_annotations, &mut IOValueDomainDecode::>::default())?.into()) } } 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<'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<'de>; fn wrap(self) -> Self::Handle { Self::Handle::new(self) } fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { match self { Shell::Atom(a) => a.write(w), Shell::Record(_) => todo!(), Shell::Sequence(items) => { w.start_sequence()?; let mut b = B::Type::default(); for e in items { b.shift(Some(B::Item::SequenceValue)); w.boundary(&b)?; e.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_sequence() } Shell::Set(items) => { w.start_set()?; let mut b = B::Type::default(); for e in items.iter() { b.shift(Some(B::Item::SetValue)); w.boundary(&b)?; e.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_set() } Shell::Dictionary(entries) => { w.start_dictionary()?; let mut b = B::Type::default(); for (k, v) in entries.iter() { b.shift(Some(B::Item::DictionaryKey)); w.boundary(&b)?; k.write(w, enc)?; b.shift(Some(B::Item::DictionaryValue)); w.boundary(&b)?; v.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_dictionary() } Shell::Embedded(d) => { w.start_embedded()?; enc.encode_embedded(w, d)?; w.end_embedded() } Shell::Annotated(b) => { let (value, anns) = b.0.as_ref(); w.start_annotations()?; let mut b = B::Type::default(); for ann in anns { b.shift(Some(B::Item::Annotation)); w.boundary(&b)?; ann.write(w, &mut IOValueDomainEncode::::default())?; } b.shift(Some(B::Item::AnnotatedValue)); w.boundary(&b)?; value.write(w, enc)?; b.shift(None); w.boundary(&b)?; w.end_annotations() } } } fn value_class(&self) -> ValueClass { match self { Shell::Atom(a) => ValueClass::Atomic(a.into()), Shell::Record(_) => ValueClass::Compound(CompoundClass::Record), Shell::Sequence(_) => ValueClass::Compound(CompoundClass::Sequence), Shell::Set(_) => ValueClass::Compound(CompoundClass::Set), Shell::Dictionary(_) => ValueClass::Compound(CompoundClass::Dictionary), Shell::Embedded(_) => ValueClass::Embedded, Shell::Annotated(b) => b.0.as_ref().0.value_class(), } } fn copy, F, Err>(w: &E::Handle, f: &mut F) -> Result where F: FnMut(&E::Embedded) -> Result { let w = w.borrow(); let r: Self::Handle = match w.value_class() { ValueClass::Atomic(a) => match a { AtomClass::Boolean => Shell::Atom(Atom::Boolean(w.as_boolean().unwrap())), AtomClass::Float => Shell::Atom(Atom::Float(w.as_float().unwrap())), AtomClass::Double => Shell::Atom(Atom::Double(w.as_double().unwrap())), AtomClass::SignedInteger => Shell::Atom(Atom::SignedInteger(w.as_signed_integer().unwrap())), AtomClass::String => Shell::Atom(Atom::String(w.as_string().unwrap())), AtomClass::ByteString => Shell::Atom(Atom::ByteString(w.as_bytestring().unwrap())), AtomClass::Symbol => Shell::Atom(Atom::Symbol(w.as_symbol().unwrap())), }.wrap(), ValueClass::Compound(c) => match c { CompoundClass::Sequence => Shell::Sequence(w.iter().map(|ww| Self::copy::(&ww, f)).collect::, _>>()?), CompoundClass::Set => Shell::Set(w.iter().map(|ww| Self::copy::(&ww, f)).collect::, _>>()?), CompoundClass::Record => Shell::Record(Record::new( Self::copy::(&w.label(), f)?, w.iter().map(|ww| Self::copy::(&ww, f)).collect::, _>>()?)), CompoundClass::Dictionary => Shell::Dictionary( w.entries().map(|(k, ww)| Ok((Self::copy::(&k, f)?, Self::copy::(&ww, f)?))) .collect::, _>>()?), }.wrap(), ValueClass::Embedded => f(&w.as_embedded().unwrap())? }; if let Some(anns) = w.annotations() { Ok(Shell::Annotated(Annotations(Box::new(( r, anns.iter().map(copy_iovalue::).map(|a| a.into()).collect() )))).wrap()) } else { Ok(r) } } 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::<'de, E>::new(Self::Mapped::::Embedded(f(d)?)))) } fn as_boolean(&self) -> Option { match self { Shell::Atom(Atom::Boolean(b)) => Some(*b), _ => None, } } fn as_float(&self) -> Option { match self { Shell::Atom(Atom::Float(f)) => Some(*f), _ => None, } } fn as_double(&self) -> Option { match self { Shell::Atom(Atom::Double(d)) => Some(*d), _ => None, } } fn as_signed_integer(&self) -> Option> { match self { Shell::Atom(Atom::SignedInteger(i)) => Some(Cow::Borrowed(i)), _ => None, } } fn as_string(&self) -> Option> { match self { Shell::Atom(Atom::String(s)) => Some(Cow::Borrowed(s)), _ => None, } } fn as_bytestring(&self) -> Option> { match self { Shell::Atom(Atom::ByteString(bs)) => Some(Cow::Borrowed(bs)), _ => None, } } fn as_symbol(&self) -> Option> { match self { Shell::Atom(Atom::Symbol(s)) => Some(Cow::Borrowed(s)), _ => None, } } fn is_record(&self) -> bool { matches!(self, Shell::Record(_)) } fn label(&self) -> Self::Handle { match self { Shell::Record(items) => items.0[0], _ => panic!("Not a record"), } } fn is_sequence(&self) -> bool { matches!(self, Shell::Sequence(_)) } fn len(&self) -> usize { match self { Shell::Record(items) => items.0.len() - 1, Shell::Sequence(items) => items.len(), Shell::Set(items) => items.len(), Shell::Dictionary(entries) => entries.len(), _ => panic!("Not a compound value"), } } fn index(&self, i: usize) -> Self::Handle { match self { Shell::Record(items) => items.0[i - 1], Shell::Sequence(items) => items[i], _ => panic!("Not indexable"), } } fn iter(&self) -> Self::Items<'_> { match self { Shell::Record(items) => items.0[1..].iter(), Shell::Sequence(items) => items.iter(), Shell::Set(items) => todo!(), // TODO: don't use slice iter directly _ => panic!("Not iterable"), } } fn is_set(&self) -> bool { matches!(self, Shell::Set(_)) } fn has>(&self, v: &E::Handle) -> bool { match self { Shell::Set(items) => todo!(), // items.contains(v), _ => false, } } fn is_dictionary(&self) -> bool { matches!(self, Shell::Dictionary(_)) } fn get>(&self, k: &K::Handle) -> Option { match self { Shell::Dictionary(entries) => todo!(), // entries.get(k), _ => None, } } fn entries(&self) -> Self::Entries<'_> { match self { Shell::Dictionary(entries) => entries.iter(), _ => panic!("Not a dictionary"), } } fn as_embedded(&self) -> Option> { match self { Shell::Embedded(d) => Some(Cow::Borrowed(d)), _ => None, } } fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>> { match self { Shell::Annotated(b) => Some(Cow::Borrowed(&b.0.as_ref().1)), _ => None, } } fn peeled(v: &Self::Handle) -> Self::Handle { match v.as_ref() { Shell::Annotated(b) => b.0.0, _ => v.clone(), } } } impl_value_methods!({'de, D: Domain<'de>}, Shell<'de, D>); impl<'de, W: Into>, D: Domain<'de>> From for Shell<'de, D> { fn from(w: W) -> Self { Shell::Atom(w.into()) } } impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { fn from(vs: Vec>) -> Self { Shell::Sequence(vs) } } impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { fn from(vs: Vec>) -> Self { vs.iter().map(|v| v.wrap()).collect::>().into() } } impl<'de, D: Domain<'de>> From>> for Shell<'de, D> { fn from(vs: Set>) -> Self { Shell::Set(vs) } } impl<'de, D: Domain<'de>> From, ShellHandle<'de, D>>> for Shell<'de, D> { fn from(vs: Map, ShellHandle<'de, D>>) -> Self { Shell::Dictionary(vs) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] pub struct Record(Vec /* at least one element, for the label */); impl Record { pub fn new(label: V, mut fields: Vec) -> Self { fields.insert(0, label); Record(fields) } pub fn _from_vec(v: Vec) -> Self { if v.is_empty() { panic!("Internal error: empty vec supplied to Record::_from_vec") } Record(v) } pub fn _vec(&self) -> &Vec { &self.0 } } #[derive(Clone)] pub struct Annotations<'de, V: ValueImpl<'de>>(Box<(V::Handle, Vec< as ValueImpl<'de>>::Handle>)>); 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<'de, V: ValueImpl<'de>> Hash for Annotations<'de, V> { fn hash(&self, state: &mut H) { self.0.as_ref().0.hash(state) } } 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<'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<'de, V: ValueImpl<'de>> Eq for Annotations<'de, V> {} 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<'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>(IOValueIso<'a>); unsafe impl<'a> TransparentWrapper> for IOValue<'a> {} impl<'de> Domain<'de> for IOValue<'de> { type Decode = IOValueDomainDecode<'de, IOValueImpl<'de>>; type Encode = IOValueDomainEncode<'de, Self>; } impl<'de> Debug for IOValue<'de> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { IOValue::peel_ref(self).fmt(f) } } 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) } } 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<'de> Borrow> for IOValue<'de> { fn borrow(&self) -> &IOValueImpl<'de> { self.0.as_ref() } } impl<'de> AsRef>>> for IOValue<'de> { fn as_ref(&self) -> &Arc>> { &self.0 } } impl<'de> FromStr for IOValue<'de> { type Err = io::Error; fn from_str(s: &str) -> Result { crate::annotated_iovalue_from_str(s) } } impl<'de> From< as ValueImpl<'de>>::Handle> for IOValue<'de> { fn from(h: as ValueImpl<'de>>::Handle) -> Self { TransparentWrapper::wrap(h) } } 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<'de> From> for as ValueImpl<'de>>::Handle { fn from(i: IOValue<'de>) -> Self { IOValue::peel(i) } } 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<'de> ValueReader<'de> for IOValue<'de> { type Impl = Self; fn read_impl + ?Sized, Dec: DomainDecode<'de, >::Embedded>>( r: &mut R, read_annotations: bool, dec: &mut Dec, ) -> Result { Ok(read(r, read_annotations, dec)?.into()) } fn read_iovalue + ?Sized>( r: &mut R, read_annotations: bool, ) -> Result<>::IOEmbedded, ReadError> { Self::read_domain(r, read_annotations, &mut IOValueDomainDecode::::default()) } } impl<'de> ValueImpl<'de> for IOValue<'de> { type Handle = Self; type Embedded = Self; 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; fn wrap(self) -> Self::Handle { self } fn value_class(&self) -> ValueClass { self.value().value_class() } fn as_boolean(&self) -> Option { self.value().as_boolean() } fn as_float(&self) -> Option { self.value().as_float() } fn as_double(&self) -> Option { self.value().as_double() } fn as_signed_integer(&self) -> Option> { self.value().as_signed_integer() } fn as_string(&self) -> Option> { self.value().as_string() } fn as_bytestring(&self) -> Option> { self.value().as_bytestring() } fn as_symbol(&self) -> Option> { self.value().as_symbol() } fn is_record(&self) -> bool { self.value().is_record() } fn label(&self) -> Self::Handle { self.value().label().into() } fn is_sequence(&self) -> bool { self.value().is_sequence() } fn len(&self) -> usize { self.value().len() } fn index(&self, i: usize) -> Self::Handle { self.value().index(i).into() } fn iter(&self) -> Self::Items<'_> { todo!() // self.value().iter() } fn is_set(&self) -> bool { self.value().is_set() } fn has>(&self, v: &E::Handle) -> bool { self.value().has::(v) } fn is_dictionary(&self) -> bool { self.value().is_dictionary() } fn get>(&self, k: &K::Handle) -> Option { self.value().get::(k).map(|v| v.into()) } fn entries(&self) -> Self::Entries<'_> { todo!() // self.value().entries() } fn as_embedded(&self) -> Option> { self.value().as_embedded() } fn annotations(&self) -> Option as ValueImpl<'de>>::Handle]>> { self.value().annotations() } fn peeled(v: &Self::Handle) -> Self::Handle { TransparentWrapper::wrap(Shell::peeled(IOValue::peel_ref(v))) } 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, 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<'de>, Dec: DomainDecode<'de, D>>( r: &mut R, read_annotations: bool, dec: &mut Dec, ) -> io::Result> { let (anns, v) = match read_annotations { true => IOValue::gather_annotations(r)?.ok_or_else(io_eof)?, false => (Vec::new(), r.skip_annotations()?.ok_or_else(io_eof)?), }; let value = match v { ValueClass::Atomic(_) => Shell::Atom(r.next_atom()?), ValueClass::Embedded => { r.open_embedded()?; let v = dec.decode_embedded(r, read_annotations)?; r.close_embedded()?; Shell::Embedded(v) } ValueClass::Compound(CompoundClass::Record) => { let mut vs = Vec::new(); r.open_record()?; let mut b = B::start(B::Item::RecordLabel); r.boundary(&b)?; vs.push(read(r, read_annotations, dec)?.wrap()); while !r.close_compound(&mut b, &B::Item::RecordField)? { vs.push(read(r, read_annotations, dec)?.wrap()); } Shell::Record(Record::_from_vec(vs)) } ValueClass::Compound(CompoundClass::Sequence) => { let mut vs = Vec::new(); r.open_sequence()?; let mut b = B::Type::default(); while !r.close_compound(&mut b, &B::Item::SequenceValue)? { vs.push(read(r, read_annotations, dec)?.wrap()); } Shell::Sequence(vs) } ValueClass::Compound(CompoundClass::Set) => { let mut s = Set::new(); r.open_set()?; let mut b = B::Type::default(); while !r.close_compound(&mut b, &B::Item::SetValue)? { s.insert(read(r, read_annotations, dec)?.wrap()); } Shell::Set(s) } ValueClass::Compound(CompoundClass::Dictionary) => { let mut d = Map::new(); r.open_dictionary()?; let mut b = B::Type::default(); while !r.close_compound(&mut b, &B::Item::DictionaryKey)? { let k = read(r, read_annotations, dec)?.wrap(); b.shift(Some(B::Item::DictionaryValue)); r.boundary(&b)?; d.insert(k, read(r, read_annotations, dec)?.wrap()); } Shell::Dictionary(d) } }; if anns.is_empty() { Ok(value) } else { Ok(Shell::Annotated(Annotations::new(value.wrap(), anns))) } }