diff --git a/implementations/rust/preserves/src/lib.rs b/implementations/rust/preserves/src/lib.rs index 4534777..b3862c0 100644 --- a/implementations/rust/preserves/src/lib.rs +++ b/implementations/rust/preserves/src/lib.rs @@ -22,13 +22,11 @@ pub use packed::iovalue_from_bytes; pub use reader::IOValues; pub use reader::Reader; pub use repr::Annotations; -pub use repr::ArcValue; pub use repr::Atom; pub use repr::Bytes; pub use repr::Embedded; pub use repr::IOValue; pub use repr::Map; -pub use repr::PlainValue; pub use repr::NoValue; pub use repr::Record; pub use repr::Set; @@ -36,9 +34,6 @@ pub use repr::Symbol; pub use repr::Value; pub use repr::ValueImpl; pub use repr::copy_via; -pub use repr::iovalue; -pub use repr::owned; -pub use repr::shell; pub use repr::value; pub use signed_integer::SignedInteger; pub use source::BinarySource; @@ -65,24 +60,24 @@ mod demo { // } #[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)]); + let l: Value = "label".parse().unwrap(); + let r = Record::new(l.value_clone(), vec![value(1), value(2), value(3)]); + let r2 = Record::new(l, vec![value(1), value(2), value(4)]); - let mut v: Map, PlainValue> = Map::new(); + let mut v: Map, Value> = 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()); + v.insert(value(123), "xyz".parse().unwrap()); + v.insert(vec![1, 2, 3].into(), "{a: 1, b: 2}".parse().unwrap()); + v.insert(value(r2), "bbb".parse().unwrap()); + v.insert(value(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"))); + println!("GETw abc {:?}", w.get(&value("abc"))); + println!("GETw 123 {:?}", w.get(&value(123))); + println!("GETw qqq {:?}", w.get(&value("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); } @@ -99,7 +94,7 @@ mod demo { } #[test] fn value_size() { - println!("Value size {}", std::mem::size_of::>()); + 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::>>()); } @@ -162,26 +157,26 @@ mod test_domain { } } - fn dom_as_preserves(v: &Dom) -> io::Result> { + fn dom_as_preserves(v: &Dom) -> io::Result> { Ok(match v { - Dom::One => owned(Bytes::new(vec![255, 255, 255, 255])), - Dom::Two => owned(Symbol::new(format!("Dom::{:?}", v))), + Dom::One => value(Bytes::new(vec![255, 255, 255, 255])), + Dom::Two => value(Symbol::new(format!("Dom::{:?}", v))), }) } #[test] fn test_one() { - let v = owned(vec![owned(1), - owned(Embedded::new(Dom::One)), - owned(2)]); - assert_eq!(PackedWriter::encode_iovalue(&iovalue(copy_via(&v, &mut dom_as_preserves).unwrap())).unwrap(), + let v = value(vec![value(1), + value(Embedded::new(Dom::One)), + value(2)]); + assert_eq!(PackedWriter::encode_iovalue(©_via(&v, &mut dom_as_preserves).unwrap().into()).unwrap(), [0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]); } #[test] fn test_two() { - let v = owned(vec![owned(1), - owned(Embedded::new(Dom::Two)), - owned(2)]); - assert_eq!(PackedWriter::encode_iovalue(&iovalue(copy_via(&v, &mut dom_as_preserves).unwrap())).unwrap(), + let v = value(vec![value(1), + value(Embedded::new(Dom::Two)), + value(2)]); + assert_eq!(PackedWriter::encode_iovalue(©_via(&v, &mut dom_as_preserves).unwrap().into()).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 55f1648..510452d 100644 --- a/implementations/rust/preserves/src/packed/mod.rs +++ b/implementations/rust/preserves/src/packed/mod.rs @@ -13,13 +13,13 @@ use crate::BytesBinarySource; use crate::Domain; use crate::DomainDecode; use crate::IOValue; -use crate::PlainValue; use crate::Reader; +use crate::Value; pub fn from_bytes<'de, D: Domain, Dec: DomainDecode>( bs: &'de [u8], decode_embedded: &mut Dec, -) -> io::Result> { +) -> io::Result> { BytesBinarySource::new(bs).packed().next(false, decode_embedded) } @@ -30,7 +30,7 @@ pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result { pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode>( bs: &'de [u8], decode_embedded: &mut Dec, -) -> io::Result> { +) -> io::Result> { super::BytesBinarySource::new(bs).packed().next(true, decode_embedded) } diff --git a/implementations/rust/preserves/src/packed/reader.rs b/implementations/rust/preserves/src/packed/reader.rs index 92ce005..4a480d7 100644 --- a/implementations/rust/preserves/src/packed/reader.rs +++ b/implementations/rust/preserves/src/packed/reader.rs @@ -300,11 +300,11 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { self.readbytes_into(&mut bs)?; Ok(Atom::Double(f64::from_bits(u64::from_be_bytes(bs)))) } - Tag::SmallInteger(v) => Ok(Atom::SignedInteger(v.into())), - Tag::MediumInteger(count) => Ok(Atom::SignedInteger(self.read_signed_integer(count.into())?)), + Tag::SmallInteger(v) => Ok(Atom::SignedInteger(Cow::Owned(v.into()))), + Tag::MediumInteger(count) => Ok(Atom::SignedInteger(Cow::Owned(self.read_signed_integer(count.into())?))), Tag::SignedInteger => { let count = self.varint()?; - Ok(Atom::SignedInteger(self.read_signed_integer(count)?)) + Ok(Atom::SignedInteger(Cow::Owned(self.read_signed_integer(count)?))) } Tag::String => { let count = self.varint()?; diff --git a/implementations/rust/preserves/src/packed/view.rs b/implementations/rust/preserves/src/packed/view.rs index c36b124..b338763 100644 --- a/implementations/rust/preserves/src/packed/view.rs +++ b/implementations/rust/preserves/src/packed/view.rs @@ -14,16 +14,12 @@ use crate::DomainDecode; use crate::IOValue; use crate::NoEmbeddedDomainCodec; use crate::PackedWriter; -use crate::PlainValue; use crate::SignedInteger; use crate::Value; use crate::ValueClass; use crate::ValueImpl; use crate::error; use crate::error::io_eof; -use crate::iovalue; -use crate::owned; -use crate::shell; use crate::reader::NextToken; use super::constants::Tag; @@ -310,8 +306,8 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe } } - fn value_clone(&self) -> PlainValue<'static, D> { - owned(View { + fn value_clone(&self) -> Value { + Value::new(View { repr: self.repr.trim(self.annotation_offset .. self.value_range.end), annotation_offset: 0, value_range: (self.value_range.start - self.annotation_offset @@ -348,22 +344,13 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe } } - fn is_signed_integer(&self) -> bool { + fn as_signed_integer(&self) -> Option> { match self.tag() { - Tag::SmallInteger(_) => true, - Tag::MediumInteger(_) => true, - Tag::SignedInteger => true, - _ => false, - } - } - - fn as_signed_integer(&self) -> Option { - match self.tag() { - Tag::SmallInteger(v) => Some(v.into()), - Tag::MediumInteger(n) => Some(self.signed_integer(self.value_range.start + 1, n as usize)), + Tag::SmallInteger(v) => Some(Cow::Owned(v.into())), + Tag::MediumInteger(n) => Some(Cow::Owned(self.signed_integer(self.value_range.start + 1, n as usize))), Tag::SignedInteger => { let (n, i) = self.varint(); - Some(self.signed_integer(i, n as usize)) + Some(Cow::Owned(self.signed_integer(i, n as usize))) } _ => None, } @@ -400,9 +387,9 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe self.tag() == Tag::Record } - fn label(&self) -> Value<'_, D> { + fn label(&self) -> Value { if !self.is_record() { panic!("Not a record") } - shell(View::inner_new(&self.repr, self.value_range.start + 1).unwrap()) + Value::new(View::inner_new(&self.repr, self.value_range.start + 1).unwrap()) } fn is_sequence(&self) -> bool { @@ -417,11 +404,11 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe } } - fn index(&self, i: usize) -> Value<'_, D> { + fn index(&self, i: usize) -> Value { self.iter().nth(i).unwrap() } - fn iter(&self) -> Box> + '_> { + fn iter(&self) -> Box> + '_> { let mut i = Box::new(ViewIterator::inner_new(&self.repr, self.value_range.start + 1)); match self.tag() { Tag::Record => { i.next(); () } @@ -436,33 +423,29 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe self.tag() == Tag::Set } - fn has(&self, v: &dyn ValueImpl) -> bool { - self.iter().find(|e| v == &**e).is_some() + fn has(&self, v: &Value) -> bool { + self.iter().find(|e| v == e).is_some() } fn is_dictionary(&self) -> bool { self.tag() == Tag::Dictionary } - fn get(&self, k: &dyn ValueImpl) -> Option> { + fn get(&self, k: &Value) -> Option> { for (kk, vv) in self.entries() { - if &*kk == k { return Some(vv); } + if k == &kk { return Some(vv); } } None } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { + fn entries(&self) -> Box, Value)> + '_> { if !self.is_dictionary() { panic!("Not a dictionary") } Box::new(DictionaryAdapter(ViewIterator::inner_new(&self.repr, self.value_range.start + 1))) } - fn is_embedded(&self) -> bool { - self.tag() == Tag::Embedded - } - - fn embedded(&self) -> Cow<'_, D> { - if !self.is_embedded() { panic!("Not an embedded value") } - match self.repr.index.embedded.as_ref() { + fn as_embedded(&self) -> Option> { + if self.tag() != Tag::Embedded { return None } + Some(match self.repr.index.embedded.as_ref() { Some(e) => { Cow::Borrowed(e.iter().find_map(|(r, d)| { if r.start == self.value_range.start { Some(d) } else { None } @@ -475,7 +458,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe let d = D::Decode::default().decode_embedded(&mut r, true).unwrap(); Cow::Owned(d) } - } + }) } fn annotations(&self) -> Option> { @@ -488,7 +471,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packe phantom: PhantomData, }); let anns: Vec = AnnotationAdapter(ViewIterator::inner_new(&repr, self.annotation_offset)) - .map(|ann| iovalue(ann.into_owned())) + .map(|ann| ann.into()) .collect(); Some(Cow::Owned(anns)) } @@ -514,7 +497,7 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode> ViewStream<'de, 'dec, D, Dec> { } impl<'de, 'dec, D: Domain, Dec: DomainDecode> Iterator for ViewStream<'de, 'dec, D, Dec> { - type Item = io::Result>; + type Item = io::Result>; fn next(&mut self) -> Option { if self.offset >= self.buf.len() { @@ -523,7 +506,7 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode> Iterator for ViewStream<'de, 'd match View::new_offset(self.buf, self.dec.as_mut().map(|dec| &mut *dec), self.offset) { Ok(v) => { self.offset = v.value_range.end; - Some(Ok(shell(v))) + Some(Ok(Value::new(v))) } Err(e) => Some(Err(e)), } @@ -543,7 +526,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ViewIterator + 'de, D: Domain> Iterator for ViewIterator> { - type Item = Value<'de, D>; + type Item = Value; fn next(&mut self) -> Option { if let Ok(Tag::End) = tag_at(self.repr.packed.as_ref(), self.offset) { @@ -551,7 +534,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for ViewIterator + 'de, D: Domain> Iterator for ViewIterator(pub ViewIterator); impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for DictionaryAdapter> { - type Item = (Value<'de, D>, Value<'de, D>); + type Item = (Value, Value); fn next(&mut self) -> Option { let k = self.0.next()?; @@ -571,7 +554,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for DictionaryAdapter(pub ViewIterator); impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for AnnotationAdapter> { - type Item = Value<'de, D>; + type Item = Value; fn next(&mut self) -> Option { if let Ok(Tag::Annotation) = tag_at(self.0.repr.packed.as_ref(), self.0.offset) { diff --git a/implementations/rust/preserves/src/reader.rs b/implementations/rust/preserves/src/reader.rs index a061305..c731361 100644 --- a/implementations/rust/preserves/src/reader.rs +++ b/implementations/rust/preserves/src/reader.rs @@ -5,8 +5,8 @@ use std::marker::PhantomData; use crate::BinarySource; use crate::CompoundClass; -use crate::PlainValue; use crate::SignedInteger; +use crate::Value; use crate::ValueClass; use crate::boundary as B; use crate::domain::Domain; @@ -23,7 +23,6 @@ use crate::repr::Map; use crate::repr::Record; use crate::repr::Set; use crate::repr::ValueImpl; -use crate::repr::owned; pub type ReaderResult = std::result::Result; @@ -144,11 +143,11 @@ pub trait Reader<'de> { } } - fn next<'produced: 'de, D: Domain, Dec: DomainDecode>( + fn next>( &mut self, read_annotations: bool, dec: &mut Dec, - ) -> io::Result> + ) -> io::Result> { let (anns, v) = match read_annotations { true => self.gather_annotations()?.ok_or_else(io_eof)?, @@ -161,7 +160,7 @@ pub trait Reader<'de> { self.open_embedded()?; let v = dec.decode_embedded(self, read_annotations)?; self.close_embedded()?; - Box::new(Embedded::new(v)) + Value::new(Embedded::new(v)) } ValueClass::Compound(CompoundClass::Record) => { let mut vs = Vec::new(); @@ -172,7 +171,7 @@ pub trait Reader<'de> { while !self.close_compound(&mut b, &B::Item::RecordField)? { vs.push(self.next(read_annotations, dec)?); } - Box::new(Record::_from_vec(vs)) + Value::new(Record::_from_vec(vs)) } ValueClass::Compound(CompoundClass::Sequence) => { let mut vs = Vec::new(); @@ -181,7 +180,7 @@ pub trait Reader<'de> { while !self.close_compound(&mut b, &B::Item::SequenceValue)? { vs.push(self.next(read_annotations, dec)?); } - Box::new(vs) + Value::new(vs) } ValueClass::Compound(CompoundClass::Set) => { let mut s = Set::new(); @@ -190,7 +189,7 @@ pub trait Reader<'de> { while !self.close_compound(&mut b, &B::Item::SetValue)? { s.insert(self.next(read_annotations, dec)?); } - Box::new(s) + Value::new(s) } ValueClass::Compound(CompoundClass::Dictionary) => { let mut d = Map::new(); @@ -202,13 +201,13 @@ pub trait Reader<'de> { self.boundary(&b)?; d.insert(k, self.next(read_annotations, dec)?); } - Box::new(d) + Value::new(d) } }; if anns.is_empty() { Ok(value) } else { - Ok(owned(Annotations::new(value, anns))) + Ok(Annotations::new(value, anns)) } } @@ -230,7 +229,7 @@ pub trait Reader<'de> { } fn next_signedinteger(&mut self) -> ReaderResult { - self.next_iovalue(false)?.as_signed_integer().ok_or(Error::Expected(ExpectedKind::SignedInteger)) + Ok(self.next_iovalue(false)?.as_signed_integer().ok_or(Error::Expected(ExpectedKind::SignedInteger))?.into_owned().into()) } fn next_i8(&mut self) -> ReaderResult { Ok(i8::try_from(&self.next_signedinteger()?)?) } diff --git a/implementations/rust/preserves/src/repr.rs b/implementations/rust/preserves/src/repr.rs index 8055d7e..1da8053 100644 --- a/implementations/rust/preserves/src/repr.rs +++ b/implementations/rust/preserves/src/repr.rs @@ -1,13 +1,11 @@ use bytemuck::TransparentWrapper; -use std::borrow::Borrow; use std::borrow::Cow; use std::cmp::Ordering; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::io; use std::marker::PhantomData; -use std::ops::Deref; use std::str::FromStr; use std::sync::Arc; use std::vec::Vec; @@ -15,7 +13,7 @@ use std::vec::Vec; pub use std::collections::BTreeSet as Set; pub use std::collections::BTreeMap as Map; -use crate::{AtomClass, TextWriter, DefaultDomainCodec, write_value}; +use crate::{AtomClass, TextWriter, DefaultDomainCodec, DebugDomainCodec}; use crate::CompoundClass; use crate::Domain; use crate::SignedInteger; @@ -26,246 +24,160 @@ use crate::domain::{NoEmbeddedDomainCodec, DomainEncode, IOValueDomainCodec}; use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64}; -pub type PlainValue<'va, D = IOValue> = Box + 'va>; - -pub enum Value<'r, D: Domain = IOValue> { - Borrowed(&'r (dyn ValueImpl + 'r)), - Shell(PlainValue<'r, D>), - Owned(PlainValue<'static, D>), -} - -impl<'r, D: Domain> Value<'r, D> { - pub fn into_owned(self: Value<'r, D>) -> PlainValue<'static, D> { - match self { - Value::Borrowed(r) => r.value_clone(), - Value::Shell(v) => v.value_clone(), - Value::Owned(v) => v, - } - } -} - -impl<'r, 'va: 'r, D: Domain> From<&'r (dyn ValueImpl + 'r)> for Value<'r, D> { - fn from(r: &'r (dyn ValueImpl + 'r)) -> Self { - Value::Borrowed(r) - } -} - -impl<'r, D: Domain> From> for Value<'r, D> { - fn from(v: PlainValue<'static, D>) -> Self { - Value::Owned(v) - } -} - -impl<'r, D: Domain> Deref for Value<'r, D> { - type Target = dyn ValueImpl + 'r; - - fn deref(&self) -> &Self::Target { - match self { - Value::Borrowed(r) => r, - Value::Shell(v) => v, - Value::Owned(v) => v, - } - } -} - -impl<'r, D: Domain> From> for ArcValue { - fn from(v: Value<'r, D>) -> Self { - v.into_owned().into() - } -} - -impl<'r> From> for IOValue { - fn from(v: Value<'r, IOValue>) -> Self { - v.into_owned().into() - } -} - -impl<'r, 'va: 'r, D: Domain> Debug for Value<'r, D> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.deref().fmt(f) - } -} - -impl<'r, 'va: 'r, D: Domain> PartialEq for Value<'r, D> { - fn eq(&self, other: &Self) -> bool { - &**self == &**other - } -} - -impl<'r, 'va: 'r, D: Domain> Eq for Value<'r, D> {} - -impl<'r, 'va: 'r, D: Domain> PartialOrd for Value<'r, D> { - fn partial_cmp(&self, other: &Self) -> Option { - Some((&**self).cmp(&**other)) - } -} - -impl<'r, 'va: 'r, D: Domain> Ord for Value<'r, D> { - fn cmp(&self, other: &Self) -> Ordering { - (&**self).cmp(&**other) - } -} - -impl<'r, 'va: 'r, D: Domain> Hash for Value<'r, D> { - fn hash(&self, state: &mut H) { - (&**self).hash(state) - } -} +#[derive(Clone, Hash, Ord, Eq, PartialOrd, PartialEq)] +#[repr(transparent)] +pub struct Value(Arc>>); /// Atomic values from the specification. -pub trait ValueImpl { - fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { - write_value(w, self, enc) - } +pub trait ValueImpl: 'static { + fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()>; - fn value_clone(&self) -> PlainValue<'static, D>; + fn value_clone(&self) -> Value; fn value_class(&self) -> ValueClass; fn as_boolean(&self) -> Option { None } fn as_float(&self) -> Option { None } fn as_double(&self) -> Option { None } - - fn is_signed_integer(&self) -> bool { false } - fn as_signed_integer(&self) -> Option { None } - + fn as_signed_integer(&self) -> Option> { None } fn as_string(&self) -> Option> { None } fn as_bytestring(&self) -> Option> { None } fn as_symbol(&self) -> Option> { None } fn is_record(&self) -> bool { false } - fn label(&self) -> Value<'_, D> { panic!("Not a record") } + fn label(&self) -> Value { panic!("Not a record") } fn is_sequence(&self) -> bool { false } fn len(&self) -> usize { panic!("Has no length") } - fn index(&self, _i: usize) -> Value<'_, D> { panic!("Not indexable") } - fn iter(&self) -> Box> + '_> { panic!("Not iterable") } + fn index(&self, _i: usize) -> Value { panic!("Not indexable") } + fn iter(&self) -> Box> + '_> { panic!("Not iterable") } fn is_set(&self) -> bool { false } - fn has(&self, _v: &dyn ValueImpl) -> bool { false } + fn has(&self, _v: &Value) -> bool { false } fn is_dictionary(&self) -> bool { false } - fn get(&self, _k: &dyn ValueImpl) -> Option> { None } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { panic!("Not a dictionary") } + fn get(&self, _k: &Value) -> Option> { None } + fn entries(&self) -> Box, Value)> + '_> { panic!("Not a dictionary") } - fn is_embedded(&self) -> bool { false } - fn embedded(&self) -> Cow<'_, D> { panic!("Not an embedded value") } + fn as_embedded(&self) -> Option> { None } fn annotations(&self) -> Option> { None } } -pub fn value>(v: &V) -> Value<'_, D> { - Value::Borrowed(v) -} - -pub fn shell<'r, D: Domain, V: ValueImpl + 'r>(v: V) -> Value<'r, D> { - Value::Shell(Box::new(v)) -} - -pub fn owned<'va, D: Domain, V: ValueImpl + 'static>(v: V) -> PlainValue<'va, D> { - Box::new(v) -} - -pub fn arcvalue + 'static>(v: V) -> ArcValue { - ArcValue(Arc::new(v)) -} - -pub fn iovalue + 'static>(v: V) -> IOValue { - IOValue(arcvalue(v)) -} - pub fn copy_via( v: &dyn ValueImpl, f: &mut F, -) -> Result, Err> +) -> Result, Err> where - F: FnMut(&D) -> Result, Err> + F: FnMut(&D) -> Result, Err> { match v.value_class() { ValueClass::Atomic(a) => Ok(match a { - AtomClass::Boolean => Box::new(v.as_boolean().unwrap()), - AtomClass::Float => Box::new(v.as_float().unwrap()), - AtomClass::Double => Box::new(v.as_double().unwrap()), - AtomClass::SignedInteger => Box::new(v.as_signed_integer().unwrap()), - AtomClass::String => Box::new(v.as_string().unwrap().into_owned()), - AtomClass::ByteString => Box::new(Bytes(v.as_bytestring().unwrap().into_owned())), - AtomClass::Symbol => Box::new(Symbol(v.as_symbol().unwrap().into_owned())), + AtomClass::Boolean => Value::new(v.as_boolean().unwrap()), + AtomClass::Float => Value::new(v.as_float().unwrap()), + AtomClass::Double => Value::new(v.as_double().unwrap()), + AtomClass::SignedInteger => Value::new(v.as_signed_integer().unwrap().into_owned()), + AtomClass::String => Value::new(v.as_string().unwrap().into_owned()), + AtomClass::ByteString => Value::new(Bytes(v.as_bytestring().unwrap().into_owned())), + AtomClass::Symbol => Value::new(Symbol(v.as_symbol().unwrap().into_owned())), }), ValueClass::Compound(c) => Ok(match c { CompoundClass::Sequence => - Box::new(v.iter().map(|w| copy_via(&*w, f)).collect::, _>>()?), + Value::new(v.iter().map(|w| copy_via(w.as_ref(), f)).collect::, _>>()?), CompoundClass::Set => - Box::new(v.iter().map(|w| copy_via(&*w, f)).collect::, _>>()?), + Value::new(v.iter().map(|w| copy_via(w.as_ref(), f)).collect::, _>>()?), CompoundClass::Record => - Box::new(Record::new( - copy_via(&*v.label(), f)?, - v.iter().map(|w| copy_via(&*w, f)).collect::, _>>()?)), + Value::new(Record::new( + copy_via(v.label().as_ref(), f)?, + v.iter().map(|w| copy_via(w.as_ref(), f)).collect::, _>>()?)), CompoundClass::Dictionary => - Box::new(v.entries().map(|(k, w)| Ok((copy_via(&*k, f)?, copy_via(&*w, f)?))) + Value::new(v.entries().map(|(k, w)| Ok((copy_via(k.as_ref(), f)?, copy_via(w.as_ref(), f)?))) .collect::, _>>()?), }), - ValueClass::Embedded => f(&v.embedded()), + ValueClass::Embedded => f(&v.as_embedded().unwrap()), } } -impl<'a, D: Domain> From<&'a dyn ValueImpl> for PlainValue<'static, D> { - fn from(v: &'a dyn ValueImpl) -> Self { - v.value_clone() +// impl<'a, D: Domain, V: ValueImpl + ?Sized> ValueImpl for &'a V { +// fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { (*self).write(w, enc) } +// fn value_clone(&self) -> PlainValue<'static, D> { (*self).value_clone() } +// fn value_class(&self) -> ValueClass { (*self).value_class() } +// fn as_boolean(&self) -> Option { (*self).as_boolean() } +// fn as_float(&self) -> Option { (*self).as_float() } +// fn as_double(&self) -> Option { (*self).as_double() } +// fn is_signed_integer(&self) -> bool { (*self).is_signed_integer() } +// fn as_signed_integer(&self) -> Option> { (*self).as_signed_integer() } +// fn as_string(&self) -> Option> { (*self).as_string() } +// fn as_bytestring(&self) -> Option> { (*self).as_bytestring() } +// fn as_symbol(&self) -> Option> { (*self).as_symbol() } +// fn is_record(&self) -> bool { (*self).is_record() } +// fn label(&self) -> Value { (*self).label() } +// fn is_sequence(&self) -> bool { (*self).is_sequence() } +// fn len(&self) -> usize { (*self).len() } +// fn index(&self, i: usize) -> Value { (*self).index(i) } +// fn iter(&self) -> Box> + '_> { (*self).iter() } +// fn is_set(&self) -> bool { (*self).is_set() } +// fn has(&self, v: &Value) -> bool { (*self).has(v) } +// fn is_dictionary(&self) -> bool { (*self).is_dictionary() } +// fn get(&self, k: &Value) -> Option> { (*self).get(k) } +// fn entries(&self) -> Box, Value)> + '_> { (*self).entries() } +// fn is_embedded(&self) -> bool { (*self).is_embedded() } +// fn embedded(&self) -> Cow<'_, D> { (*self).embedded() } +// fn annotations(&self) -> Option> { (*self).annotations() } +// } + +impl Value { + pub fn new>(v: V) -> Self { + Value(Arc::new(Box::new(v))) } } -impl<'a, D: Domain, V: ValueImpl + ?Sized> ValueImpl for &'a V { - fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { (*self).write(w, enc) } - fn value_clone(&self) -> PlainValue<'static, D> { (*self).value_clone() } - fn value_class(&self) -> ValueClass { (*self).value_class() } - fn as_boolean(&self) -> Option { (*self).as_boolean() } - fn as_float(&self) -> Option { (*self).as_float() } - fn as_double(&self) -> Option { (*self).as_double() } - fn is_signed_integer(&self) -> bool { (*self).is_signed_integer() } - fn as_signed_integer(&self) -> Option { (*self).as_signed_integer() } - fn as_string(&self) -> Option> { (*self).as_string() } - fn as_bytestring(&self) -> Option> { (*self).as_bytestring() } - fn as_symbol(&self) -> Option> { (*self).as_symbol() } - fn is_record(&self) -> bool { (*self).is_record() } - fn label(&self) -> Value<'_, D> { (*self).label() } - fn is_sequence(&self) -> bool { (*self).is_sequence() } - fn len(&self) -> usize { (*self).len() } - fn index(&self, i: usize) -> Value<'_, D> { (*self).index(i) } - fn iter(&self) -> Box> + '_> { (*self).iter() } - fn is_set(&self) -> bool { (*self).is_set() } - fn has(&self, v: &dyn ValueImpl) -> bool { (*self).has(v) } - fn is_dictionary(&self) -> bool { (*self).is_dictionary() } - fn get(&self, k: &dyn ValueImpl) -> Option> { (*self).get(k) } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { (*self).entries() } - fn is_embedded(&self) -> bool { (*self).is_embedded() } - fn embedded(&self) -> Cow<'_, D> { (*self).embedded() } - fn annotations(&self) -> Option> { (*self).annotations() } +pub fn value>(v: V) -> Value { + Value::new(v) } -impl<'va, D: Domain> ValueImpl for PlainValue<'va, D> { +impl Debug for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + TextWriter::fmt_value(f, &mut DefaultDomainCodec, self).map_err(|_| std::fmt::Error) + } +} + +impl, D: Domain + FromStr> FromStr for Value { + type Err = io::Error; + + fn from_str(s: &str) -> Result { + crate::from_str(s, &mut DebugDomainCodec) + } +} + +impl<'a, D: Domain> AsRef + 'a> for Value { + fn as_ref(&self) -> &(dyn ValueImpl + 'a) { + (*self.0).as_ref() + } +} + +impl ValueImpl for Value { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { self.as_ref().write(w, enc) } - fn value_clone(&self) -> PlainValue<'static, D> { self.as_ref().value_clone() } + fn value_clone(&self) -> Value { self.as_ref().value_clone() } fn value_class(&self) -> ValueClass { self.as_ref().value_class() } fn as_boolean(&self) -> Option { self.as_ref().as_boolean() } fn as_float(&self) -> Option { self.as_ref().as_float() } fn as_double(&self) -> Option { self.as_ref().as_double() } - fn is_signed_integer(&self) -> bool { self.as_ref().is_signed_integer() } - fn as_signed_integer(&self) -> Option { self.as_ref().as_signed_integer() } + fn as_signed_integer(&self) -> Option> { self.as_ref().as_signed_integer() } fn as_string(&self) -> Option> { self.as_ref().as_string() } fn as_bytestring(&self) -> Option> { self.as_ref().as_bytestring() } fn as_symbol(&self) -> Option> { self.as_ref().as_symbol() } fn is_record(&self) -> bool { self.as_ref().is_record() } - fn label(&self) -> Value<'_, D> { self.as_ref().label() } + fn label(&self) -> Value { self.as_ref().label() } fn is_sequence(&self) -> bool { self.as_ref().is_sequence() } fn len(&self) -> usize { self.as_ref().len() } - fn index(&self, i: usize) -> Value<'_, D> { self.as_ref().index(i) } - fn iter(&self) -> Box> + '_> { self.as_ref().iter() } + fn index(&self, i: usize) -> Value { self.as_ref().index(i) } + fn iter(&self) -> Box> + '_> { self.as_ref().iter() } fn is_set(&self) -> bool { self.as_ref().is_set() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.as_ref().has(v) } + fn has(&self, v: &Value) -> bool { self.as_ref().has(v) } fn is_dictionary(&self) -> bool { self.as_ref().is_dictionary() } - fn get(&self, k: &dyn ValueImpl) -> Option> { self.as_ref().get(k) } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { self.as_ref().entries() } - fn is_embedded(&self) -> bool { self.as_ref().is_embedded() } - fn embedded(&self) -> Cow<'_, D> { self.as_ref().embedded() } + fn get(&self, k: &Value) -> Option> { self.as_ref().get(k) } + fn entries(&self) -> Box, Value)> + '_> { self.as_ref().entries() } + fn as_embedded(&self) -> Option> { self.as_ref().as_embedded() } fn annotations(&self) -> Option> { self.as_ref().annotations() } } @@ -275,14 +187,6 @@ impl<'a, D: Domain> Debug for dyn ValueImpl + 'a { } } -impl, D: Domain + FromStr> FromStr for PlainValue<'static, D> { - type Err = io::Error; - - fn from_str(s: &str) -> Result { - Ok(crate::annotated_from_str(s, &mut DefaultDomainCodec)?.value_clone()) - } -} - impl<'a, D: Domain> Hash for dyn ValueImpl + 'a { fn hash(&self, state: &mut H) { match self.value_class() { @@ -314,7 +218,7 @@ impl<'a, D: Domain> Hash for dyn ValueImpl + 'a { } } } - ValueClass::Embedded => self.embedded().hash(state), + ValueClass::Embedded => self.as_embedded().unwrap().hash(state), } } } @@ -359,7 +263,7 @@ impl<'a, D: Domain> PartialEq for dyn ValueImpl + 'a { d1 == d2 } } - ValueClass::Embedded => self.embedded() == other.embedded(), + ValueClass::Embedded => self.as_embedded().unwrap() == other.as_embedded().unwrap(), } } } @@ -376,7 +280,7 @@ impl<'a, D: Domain> Ord for dyn ValueImpl + 'a { AtomClass::Double => cmp_f64(self.as_double().unwrap(), other.as_double().unwrap()), AtomClass::SignedInteger => - self.as_signed_integer().cmp(&other.as_signed_integer()), + self.as_signed_integer().unwrap().cmp(&other.as_signed_integer().unwrap()), AtomClass::String => self.as_string().cmp(&other.as_string()), AtomClass::ByteString => @@ -400,7 +304,7 @@ impl<'a, D: Domain> Ord for dyn ValueImpl + 'a { d1.cmp(&d2) } }, - ValueClass::Embedded => self.embedded().cmp(&other.embedded()), + ValueClass::Embedded => self.as_embedded().unwrap().cmp(&other.as_embedded().unwrap()), }) } } @@ -418,26 +322,36 @@ pub enum Atom<'a> { Boolean(bool), Float(f32), Double(f64), - SignedInteger(SignedInteger), + SignedInteger(Cow<'a, SignedInteger>), String(Cow<'a, str>), ByteString(Cow<'a, [u8]>), Symbol(Cow<'a, str>), } impl<'a> Atom<'a> { - pub fn into_value<'b: 'a, D: Domain>(self) -> PlainValue<'b, D> { + pub fn into_value(self) -> Value { match self { - Atom::Boolean(b) => Box::new(b), - Atom::Float(f) => Box::new(f), - Atom::Double(d) => Box::new(d), - Atom::SignedInteger(i) => Box::new(i), - Atom::String(s) => Box::new(s.into_owned()), - Atom::ByteString(bs) => Box::new(Bytes(bs.into_owned())), - Atom::Symbol(s) => Box::new(Symbol(s.into_owned())), + Atom::Boolean(b) => Value::new(b), + Atom::Float(f) => Value::new(f), + Atom::Double(d) => Value::new(d), + Atom::SignedInteger(i) => Value::new(i.into_owned()), + Atom::String(s) => Value::new(s.into_owned()), + Atom::ByteString(bs) => Value::new(Bytes(bs.into_owned())), + Atom::Symbol(s) => Value::new(Symbol(s.into_owned())), } } } +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<'r, 'a> From<&'r Atom<'a>> for AtomClass { fn from(a: &'r Atom<'a>) -> Self { match a { @@ -465,7 +379,7 @@ impl<'a, D: Domain> ValueImpl for Atom<'a> { } } - fn value_clone(&self) -> PlainValue<'static, D> { + fn value_clone(&self) -> Value { self.clone().into_value() } @@ -485,9 +399,8 @@ impl<'a, D: Domain> ValueImpl for Atom<'a> { if let Atom::Double(d) = self { Some(*d) } else { None } } - fn is_signed_integer(&self) -> bool { matches!(self, Atom::SignedInteger(_)) } - fn as_signed_integer(&self) -> Option { - if let Atom::SignedInteger(i) = self { Some(i.clone()) } else { None } + fn as_signed_integer(&self) -> Option> { + if let Atom::SignedInteger(i) = self { Some(Cow::Borrowed(i)) } else { None } } fn as_string(&self) -> Option> { @@ -521,38 +434,38 @@ impl FromStr for NoValue { impl ValueImpl for NoValue { fn write(&self, _w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { unreachable!() } - fn value_clone(&self) -> PlainValue<'static, D> { unreachable!() } + fn value_clone(&self) -> Value { unreachable!() } fn value_class(&self) -> ValueClass { unreachable!() } } impl ValueImpl for bool { fn write(&self, w: &mut dyn Writer, __enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_bool(*self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(*self) } + fn value_clone(&self) -> Value { Value::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Boolean) } fn as_boolean(&self) -> Option { Some(*self) } } impl ValueImpl for u64 { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_u64(*self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(*self) } + fn value_clone(&self) -> Value { Value::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) } - fn as_signed_integer(&self) -> Option { - Some((*self).into()) + fn as_signed_integer(&self) -> Option> { + Some(Cow::Owned(SignedInteger::from(*self))) } } impl ValueImpl for SignedInteger { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_signed_integer(self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(self.clone()) } + fn value_clone(&self) -> Value { Value::new(self.clone()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) } - fn as_signed_integer(&self) -> Option { - Some(self.clone()) + fn as_signed_integer(&self) -> Option> { + Some(Cow::Borrowed(self)) } } impl ValueImpl for f32 { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_f32(*self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(*self) } + fn value_clone(&self) -> Value { Value::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Float) } fn as_float(&self) -> Option { Some(*self) } fn as_double(&self) -> Option { Some(*self as f64) } @@ -560,22 +473,22 @@ impl ValueImpl for f32 { impl ValueImpl for f64 { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_f64(*self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(*self) } + fn value_clone(&self) -> Value { Value::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Float) } fn as_float(&self) -> Option { Some(*self as f32) } fn as_double(&self) -> Option { Some(*self) } } -impl ValueImpl for str { +impl<'a, D: Domain> ValueImpl for &'a str { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_string(self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(self.to_owned()) } + fn value_clone(&self) -> Value { Value::new(self.to_owned()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) } fn as_string(&self) -> Option> { Some(Cow::Borrowed(self)) } } impl ValueImpl for String { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_string(self) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(self.clone()) } + fn value_clone(&self) -> Value { Value::new(self.clone()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) } fn as_string(&self) -> Option> { Some(Cow::Borrowed(self)) } } @@ -590,9 +503,9 @@ impl + Debug> Bytes { } } -impl + Debug, D: Domain> ValueImpl for Bytes { +impl + Debug + 'static, D: Domain> ValueImpl for Bytes { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_bytes(self.0.as_ref()) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(Bytes(self.0.as_ref().to_owned())) } + fn value_clone(&self) -> Value { Value::new(Bytes(self.0.as_ref().to_owned())) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::ByteString) } fn as_bytestring(&self) -> Option> { Some(Cow::Borrowed(self.0.as_ref())) } } @@ -607,9 +520,9 @@ impl + Debug> Symbol { } } -impl + Debug, D: Domain> ValueImpl for Symbol { +impl + Debug + 'static, D: Domain> ValueImpl for Symbol { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { w.write_symbol(self.0.as_ref()) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(Symbol(self.0.as_ref().to_owned())) } + fn value_clone(&self) -> Value { Value::new(Symbol(self.0.as_ref().to_owned())) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Symbol) } fn as_symbol(&self) -> Option> { Some(Cow::Borrowed(self.0.as_ref())) } } @@ -634,7 +547,7 @@ impl Record { } } -impl> ValueImpl for Record { +impl ValueImpl for Record> { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_record()?; let mut b = B::start(B::Item::RecordLabel); @@ -650,39 +563,39 @@ impl> ValueImpl for Record { w.end_record() } - fn value_clone(&self) -> PlainValue<'static, D> { - Box::new(Record(self.0.iter().map(|v| v.value_clone()).collect())) + fn value_clone(&self) -> Value { + Value::new(Record(self.0.iter().map(|v| v.value_clone()).collect())) } fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Record) } fn is_record(&self) -> bool { true } - fn label(&self) -> Value<'_, D> { Value::Borrowed(&self.0[0]) } + fn label(&self) -> Value { self.0[0].clone() } fn len(&self) -> usize { self.0.len() - 1 } - fn index(&self, i: usize) -> Value<'_, D> { Value::Borrowed(&self.0[i + 1]) } - fn iter(&self) -> Box> + '_> { - Box::new(self.0[1..].iter().map(value)) + fn index(&self, i: usize) -> Value { self.0[i + 1].clone() } + fn iter(&self) -> Box> + '_> { + Box::new(self.0[1..].iter().cloned()) } } -impl> ValueImpl for Vec { +impl ValueImpl for Vec> { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { (&self[..]).write(w, enc) } - fn value_clone(&self) -> PlainValue<'static, D> { + fn value_clone(&self) -> Value { (&self[..]).value_clone() } fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) } fn is_sequence(&self) -> bool { true } fn len(&self) -> usize { self.len() } - fn index(&self, i: usize) -> Value<'_, D> { Value::Borrowed(&self[i]) } - fn iter(&self) -> Box> + '_> { - Box::new(self[..].iter().map(value)) + fn index(&self, i: usize) -> Value { self[i].clone() } + fn iter(&self) -> Box> + '_> { + Box::new(self[..].iter().cloned()) } } -impl> ValueImpl for [V] { +impl ValueImpl for [Value] { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_sequence()?; let mut b = B::Type::default(); @@ -696,77 +609,54 @@ impl> ValueImpl for [V] { w.end_sequence() } - fn value_clone(&self) -> PlainValue<'static, D> { - Box::new(self.iter().map(|v| v.value_clone()).collect::>()) + fn value_clone(&self) -> Value { + Value::new(self.iter().map(|v| v.value_clone()).collect::>()) } fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) } fn is_sequence(&self) -> bool { true } fn len(&self) -> usize { self.len() } - fn index(&self, i: usize) -> Value<'_, D> { Value::Borrowed(&self[i]) } - fn iter(&self) -> Box> + '_> { - Box::new(self[..].iter().map(value)) + fn index(&self, i: usize) -> Value { self[i].clone() } + fn iter(&self) -> Box> + '_> { + Box::new(self[..].iter().cloned()) } } -impl Borrow> + Ord + 'static> ValueImpl for Set { +impl ValueImpl for Set> { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_set()?; let mut b = B::Type::default(); for e in self { b.shift(Some(B::Item::SetValue)); w.boundary(&b)?; - Key::peel_ref(e.borrow()).write(w, enc)?; + e.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_set() } - fn value_clone(&self) -> PlainValue<'static, D> { - Box::new(self.iter().map(|v| Key::peel_ref(&v.borrow()).value_clone()).collect::>()) + fn value_clone(&self) -> Value { + Value::new(self.iter().map(|v| v.value_clone()).collect::>()) } fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Set) } fn is_set(&self) -> bool { true } fn len(&self) -> usize { self.len() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.contains(&Key::wrap_ref(v)) } - fn iter(&self) -> Box> + '_> { - Box::new(self.iter().map(|e| Value::Borrowed(Key::peel_ref(&e.borrow())))) + fn has(&self, v: &Value) -> bool { self.contains(v) } + fn iter(&self) -> Box> + '_> { + Box::new(self.iter().map(|v| v.value_clone())) } } -// Many thanks to SkiFire13 and the other participants in -// https://users.rust-lang.org/t/is-the-lifetime-of-a-btreemap-get-result-attached-to-the-key-as-well-as-the-map/83568/7 -// for the idea of using TransparentWrapper here. -// -#[derive(PartialEq, Eq, PartialOrd, Ord)] -#[repr(transparent)] -pub struct Key<'a, D: Domain>(pub dyn ValueImpl + 'a); -unsafe impl<'a, D: Domain> TransparentWrapper + 'a> for Key<'a, D> {} - -impl<'a, 'b: 'a, D: Domain> Borrow> for PlainValue<'b, D> { - fn borrow(&self) -> &Key<'a, D> { - Key::wrap_ref(&**self) - } -} - -impl<'a, 'b: 'a, D: Domain> Borrow> for &'b (dyn ValueImpl + 'b) { - fn borrow(&self) -> &Key<'a, D> { - Key::wrap_ref(self) - } -} - -impl + 'static, K: for<'a> Borrow> + Ord + 'static> ValueImpl - for Map -{ +impl ValueImpl for Map, Value> { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_dictionary()?; let mut b = B::Type::default(); for (k, v) in self { b.shift(Some(B::Item::DictionaryKey)); w.boundary(&b)?; - Key::peel_ref(k.borrow()).write(w, enc)?; + k.write(w, enc)?; b.shift(Some(B::Item::DictionaryValue)); w.boundary(&b)?; v.write(w, enc)?; @@ -776,23 +666,19 @@ impl + 'static, K: for<'a> Borrow> + Ord + w.end_dictionary() } - fn value_clone(&self) -> PlainValue<'static, D> { - Box::new(ValueImpl::entries(self).map(|(k, v)| (k.value_clone(), v.value_clone())).collect::>()) + fn value_clone(&self) -> Value { + Value::new(ValueImpl::entries(self).map(|(k, v)| (k.value_clone(), v.value_clone())).collect::>()) } fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Dictionary) } fn is_dictionary(&self) -> bool { true } fn len(&self) -> usize { self.len() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.contains_key(&Key::wrap_ref(v)) } - fn get(&self, k: &dyn ValueImpl) -> Option> { - match Map::get(self, &Key::wrap_ref(k)) { - Some(v) => Some(Value::Borrowed(v)), - None => None, - } + fn has(&self, v: &Value) -> bool { self.contains_key(v) } + fn get(&self, k: &Value) -> Option> { + Map::get(self, &k).map(Value::clone) } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { - Box::new(self.iter().map( - |(k,v)| (Value::Borrowed(Key::peel_ref(&k.borrow())), value(v)))) + fn entries(&self) -> Box, Value)> + '_> { + Box::new(self.iter().map(|(k,v)| (k.clone(), v.clone()))) } } @@ -821,18 +707,21 @@ impl ValueImpl for Embedded { w.end_embedded() } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(self.clone()) } + fn value_clone(&self) -> Value { Value::new(self.clone()) } fn value_class(&self) -> ValueClass { ValueClass::Embedded } - fn is_embedded(&self) -> bool { true } - fn embedded(&self) -> Cow<'_, D> { Cow::Borrowed(&self.0) } + fn as_embedded(&self) -> Option> { Some(Cow::Borrowed(&self.0)) } } #[derive(Debug)] pub struct Annotations + 'static>(V, Vec, PhantomData); impl> Annotations { - pub fn new(value: V, anns: Vec) -> Self { - Annotations(value, anns, PhantomData) + pub fn new(value: V, anns: Vec) -> Value { + if anns.is_empty() { + Value::new(value) + } else { + Value::new(Annotations(value, anns, PhantomData)) + } } pub fn value(&self) -> &dyn ValueImpl { @@ -842,59 +731,53 @@ impl> Annotations { impl> ValueImpl for Annotations { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { - if !self.1.is_empty() { - w.start_annotations()?; - let mut b = B::Type::default(); - for ann in &self.1 { - b.shift(Some(B::Item::Annotation)); - w.boundary(&b)?; - ann.write(w, &mut IOValueDomainCodec)?; - } - b.shift(Some(B::Item::AnnotatedValue)); + w.start_annotations()?; + let mut b = B::Type::default(); + for ann in &self.1 { + b.shift(Some(B::Item::Annotation)); w.boundary(&b)?; - self.0.write(w, enc)?; - b.shift(None); - w.boundary(&b)?; - w.end_annotations() - } else { - self.0.write(w, enc) + ann.write(w, &mut IOValueDomainCodec)?; } + b.shift(Some(B::Item::AnnotatedValue)); + w.boundary(&b)?; + self.0.write(w, enc)?; + b.shift(None); + w.boundary(&b)?; + w.end_annotations() } - fn value_clone(&self) -> PlainValue<'static, D> { - Box::new(Annotations(self.0.value_clone(), - self.1.iter().map(|v| v.value_clone().into()).collect(), - PhantomData)) + fn value_clone(&self) -> Value { + Value::new(Annotations(self.0.value_clone(), + self.1.iter().map(|v| v.value_clone().into()).collect(), + PhantomData)) } 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 is_signed_integer(&self) -> bool { self.value().is_signed_integer() } - fn as_signed_integer(&self) -> Option { self.value().as_signed_integer() } + 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) -> Value<'_, D> { self.value().label() } + fn label(&self) -> Value { self.value().label() } fn is_sequence(&self) -> bool { self.value().is_sequence() } fn len(&self) -> usize { self.value().len() } - fn index(&self, i: usize) -> Value<'_, D> { self.value().index(i) } - fn iter(&self) -> Box> + '_> { self.value().iter() } + fn index(&self, i: usize) -> Value { self.value().index(i) } + fn iter(&self) -> Box> + '_> { self.value().iter() } fn is_set(&self) -> bool { self.value().is_set() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.value().has(v) } + fn has(&self, v: &Value) -> bool { self.value().has(v) } fn is_dictionary(&self) -> bool { self.value().is_dictionary() } - fn get(&self, k: &dyn ValueImpl) -> Option> { self.value().get(k) } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { self.value().entries() } - fn is_embedded(&self) -> bool { self.value().is_embedded() } - fn embedded(&self) -> Cow<'_, D> { self.value().embedded() } + fn get(&self, k: &Value) -> Option> { self.value().get(k) } + fn entries(&self) -> Box, Value)> + '_> { self.value().entries() } + fn as_embedded(&self) -> Option> { self.value().as_embedded() } fn annotations(&self) -> Option> { Some(Cow::Borrowed(&self.1)) } } impl> PartialEq for Annotations { fn eq(&self, other: &Self) -> bool { - self.value().eq(&other.value()) + self.value().eq(other.value()) } } @@ -914,41 +797,18 @@ impl> PartialOrd for Annotations { impl> Ord for Annotations { fn cmp(&self, other: &Self) -> Ordering { - self.value().cmp(&other.value()) + self.value().cmp(other.value()) } } -#[derive(Clone, Eq, Hash, PartialOrd, Ord)] -#[repr(transparent)] -pub struct ArcValue(Arc>); - #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] -pub struct IOValue(ArcValue); - -impl Debug for ArcValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - value(self).fmt(f) - } -} +pub struct IOValue(Value); +unsafe impl TransparentWrapper> for IOValue {} impl Debug for IOValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - value(self).fmt(f) - } -} - -impl PartialEq for ArcValue { - fn eq(&self, other: &Self) -> bool { - &self.0 == &other.0 - } -} - -impl, D: Domain + FromStr> FromStr for ArcValue { - type Err = io::Error; - - fn from_str(s: &str) -> Result { - Ok(arcvalue(crate::annotated_from_str(s, &mut DefaultDomainCodec)?.value_clone())) + self.0.fmt(f) } } @@ -960,88 +820,86 @@ impl FromStr for IOValue { } } -impl From> for ArcValue { - fn from(b: PlainValue<'static, D>) -> Self { - ArcValue(Arc::from(b)) - } -} - -impl From> for IOValue { - fn from(b: PlainValue<'static, IOValue>) -> Self { - IOValue(b.into()) - } -} - -impl From> for IOValue { - fn from(b: ArcValue) -> Self { +impl From> for IOValue { + fn from(b: Value) -> Self { IOValue(b) } } -impl<'a> Borrow> for IOValue { - fn borrow(&self) -> &Key<'a, IOValue> { - Key::wrap_ref(&*self.0.0) +impl From for Value { + fn from(b: IOValue) -> Self { + b.0 } } -impl<'a, D: Domain> Borrow> for ArcValue { - fn borrow(&self) -> &Key<'a, D> { - Key::wrap_ref(&*self.0) +impl> From> for Value { + fn from(v: Vec) -> Self { + value(v.into_iter().map(value).collect::>()) } } -impl ValueImpl for ArcValue { - fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { self.0.write(w, enc) } - fn value_clone(&self) -> PlainValue<'static, D> { Box::new(self.clone()) } - fn value_class(&self) -> ValueClass { self.0.value_class() } - fn as_boolean(&self) -> Option { self.0.as_boolean() } - fn as_float(&self) -> Option { self.0.as_float() } - fn as_double(&self) -> Option { self.0.as_double() } - fn is_signed_integer(&self) -> bool { self.0.is_signed_integer() } - fn as_signed_integer(&self) -> Option { self.0.as_signed_integer() } - fn as_string(&self) -> Option> { self.0.as_string() } - fn as_bytestring(&self) -> Option> { self.0.as_bytestring() } - fn as_symbol(&self) -> Option> { self.0.as_symbol() } - fn is_record(&self) -> bool { self.0.is_record() } - fn label(&self) -> Value<'_, D> { self.0.label() } - fn is_sequence(&self) -> bool { self.0.is_sequence() } - fn len(&self) -> usize { self.0.len() } - fn index(&self, i: usize) -> Value<'_, D> { self.0.index(i) } - fn iter(&self) -> Box> + '_> { self.0.iter() } - fn is_set(&self) -> bool { self.0.is_set() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.0.has(v) } - fn is_dictionary(&self) -> bool { self.0.is_dictionary() } - fn get(&self, k: &dyn ValueImpl) -> Option> { self.0.get(k) } - fn entries(&self) -> Box, Value<'_, D>)> + '_> { self.0.entries() } - fn is_embedded(&self) -> bool { self.0.is_embedded() } - fn embedded(&self) -> Cow<'_, D> { self.0.embedded() } - fn annotations(&self) -> Option> { self.0.annotations() } +impl<'a> From<&'a Value> for &'a IOValue { + fn from(b: &'a Value) -> Self { + IOValue::wrap_ref(b) + } } +impl<'a> From<&'a IOValue> for &'a Value { + fn from(b: &'a IOValue) -> Self { + IOValue::peel_ref(b) + } +} + +// impl ValueImpl for ArcValue { +// fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { self.0.write(w, enc) } +// fn value_clone(&self) -> Value { Value::new(self.clone()) } +// fn value_class(&self) -> ValueClass { self.0.value_class() } +// fn as_boolean(&self) -> Option { self.0.as_boolean() } +// fn as_float(&self) -> Option { self.0.as_float() } +// fn as_double(&self) -> Option { self.0.as_double() } +// fn is_signed_integer(&self) -> bool { self.0.is_signed_integer() } +// fn as_signed_integer(&self) -> Option> { self.0.as_signed_integer() } +// fn as_string(&self) -> Option> { self.0.as_string() } +// fn as_bytestring(&self) -> Option> { self.0.as_bytestring() } +// fn as_symbol(&self) -> Option> { self.0.as_symbol() } +// fn is_record(&self) -> bool { self.0.is_record() } +// fn label(&self) -> Value { self.0.label() } +// fn is_sequence(&self) -> bool { self.0.is_sequence() } +// fn len(&self) -> usize { self.0.len() } +// fn index(&self, i: usize) -> Value { self.0.index(i) } +// fn iter(&self) -> Box> + '_> { self.0.iter() } +// fn is_set(&self) -> bool { self.0.is_set() } +// fn has(&self, v: &Value) -> bool { self.0.has(v) } +// fn is_dictionary(&self) -> bool { self.0.is_dictionary() } +// fn get(&self, k: &Value) -> Option> { self.0.get(k) } +// fn entries(&self) -> Box, Value)> + '_> { self.0.entries() } +// fn is_embedded(&self) -> bool { self.0.is_embedded() } +// fn embedded(&self) -> Cow<'_, D> { self.0.embedded() } +// fn annotations(&self) -> Option> { self.0.annotations() } +// } + impl ValueImpl for IOValue { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { self.0.write(w, enc) } - fn value_clone(&self) -> PlainValue<'static, IOValue> { Box::new(self.clone()) } + fn value_clone(&self) -> Value { Value::new(self.clone()) } fn value_class(&self) -> ValueClass { self.0.value_class() } fn as_boolean(&self) -> Option { self.0.as_boolean() } fn as_float(&self) -> Option { self.0.as_float() } fn as_double(&self) -> Option { self.0.as_double() } - fn is_signed_integer(&self) -> bool { self.0.is_signed_integer() } - fn as_signed_integer(&self) -> Option { self.0.as_signed_integer() } + fn as_signed_integer(&self) -> Option> { self.0.as_signed_integer() } fn as_string(&self) -> Option> { self.0.as_string() } fn as_bytestring(&self) -> Option> { self.0.as_bytestring() } fn as_symbol(&self) -> Option> { self.0.as_symbol() } fn is_record(&self) -> bool { self.0.is_record() } - fn label(&self) -> Value<'_, IOValue> { self.0.label() } + fn label(&self) -> Value { self.0.label() } fn is_sequence(&self) -> bool { self.0.is_sequence() } fn len(&self) -> usize { self.0.len() } - fn index(&self, i: usize) -> Value<'_, IOValue> { self.0.index(i) } - fn iter(&self) -> Box> + '_> { self.0.iter() } + fn index(&self, i: usize) -> Value { self.0.index(i) } + fn iter(&self) -> Box> + '_> { self.0.iter() } fn is_set(&self) -> bool { self.0.is_set() } - fn has(&self, v: &dyn ValueImpl) -> bool { self.0.has(v) } + fn has(&self, v: &Value) -> bool { self.0.has(v) } fn is_dictionary(&self) -> bool { self.0.is_dictionary() } - fn get(&self, k: &dyn ValueImpl) -> Option> { self.0.get(k) } - fn entries(&self) -> Box, Value<'_, IOValue>)> + '_> { self.0.entries() } - fn is_embedded(&self) -> bool { self.0.is_embedded() } - fn embedded(&self) -> Cow<'_, IOValue> { self.0.embedded() } + fn get(&self, k: &Value) -> Option> { self.0.get(k) } + fn entries(&self) -> Box, Value)> + '_> { self.0.entries() } + fn as_embedded(&self) -> Option> { self.0.as_embedded() } fn annotations(&self) -> Option> { self.0.annotations() } } diff --git a/implementations/rust/preserves/src/text/mod.rs b/implementations/rust/preserves/src/text/mod.rs index 73aa688..7235702 100644 --- a/implementations/rust/preserves/src/text/mod.rs +++ b/implementations/rust/preserves/src/text/mod.rs @@ -11,13 +11,13 @@ use crate::BytesBinarySource; use crate::Domain; use crate::DomainDecode; use crate::IOValue; -use crate::PlainValue; use crate::Reader; +use crate::Value; pub fn from_str<'de, D: Domain, Dec: DomainDecode>( s: &'de str, decode_embedded: &mut Dec, -) -> io::Result> { +) -> io::Result> { BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded) } @@ -28,7 +28,7 @@ pub fn iovalue_from_str(s: &str) -> io::Result { pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode>( s: &'de str, decode_embedded: &mut Dec, -) -> io::Result> { +) -> io::Result> { BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded) } @@ -39,16 +39,16 @@ pub fn annotated_iovalue_from_str(s: &str) -> io::Result { #[cfg(test)] mod formatting_tests { use crate::IOValue; + use crate::Value; 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(); 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(); assert_eq!(format!("{:#?}", &v), concat!( "[\n", " 1,\n", @@ -84,7 +84,7 @@ mod unusual_float_tests { fn d32(u: u32, expected: &str) { let v = f32::from_bits(u); - let w = iovalue(v); + let w = value(v).into(); assert_eq!(format!("{:?}", w), expected); let x = expected.parse::().unwrap(); assert_eq!(x, w); @@ -92,7 +92,7 @@ mod unusual_float_tests { fn d64(u: u64, expected: &str) { let v = f64::from_bits(u); - let w = iovalue(v); + let w = value(v).into(); assert_eq!(format!("{:?}", w), expected); let x = expected.parse::().unwrap(); assert_eq!(x, w); diff --git a/implementations/rust/preserves/src/text/reader.rs b/implementations/rust/preserves/src/text/reader.rs index f382672..a35efa4 100644 --- a/implementations/rust/preserves/src/text/reader.rs +++ b/implementations/rust/preserves/src/text/reader.rs @@ -266,9 +266,10 @@ impl<'de, S: BinarySource<'de>> TextReader<'de, S> return match NUMBER_RE.captures(&s) { None => Ok(Atom::Symbol(s.into())), Some(m) => match m.get(2) { - None => Ok(Atom::SignedInteger(s.parse::().map_err( - |_| self.syntax_error(&format!( - "Invalid signed-integer number: {:?}", s)))?.into())), + None => Ok(Atom::SignedInteger(Cow::Owned( + s.parse::().map_err( + |_| self.syntax_error(&format!( + "Invalid signed-integer number: {:?}", s)))?.into()))), Some(_) => { if let Some(maybe_f) = m.get(7) { let s = m[1].to_owned() + &m[3]; diff --git a/implementations/rust/preserves/src/writer.rs b/implementations/rust/preserves/src/writer.rs index cafc347..bb6e23b 100644 --- a/implementations/rust/preserves/src/writer.rs +++ b/implementations/rust/preserves/src/writer.rs @@ -70,9 +70,9 @@ pub trait Writer { fn specialized(&mut self) -> Option<(&str, &mut dyn io::Write)> { None } } -pub fn write_value>( +pub fn write_value( w: &mut dyn Writer, - v: V, + v: &dyn ValueImpl, enc: &mut dyn DomainEncode, ) -> io::Result<()> { let annotations = v.annotations(); @@ -163,7 +163,7 @@ pub fn write_value>( } ValueClass::Embedded => { w.start_embedded()?; - enc.encode_embedded(w, &v.embedded())?; + enc.encode_embedded(w, &v.as_embedded().unwrap())?; w.end_embedded()? } }