use bytemuck::TransparentWrapper; use std::any::Any; use std::borrow::{Cow, Borrow}; use std::cmp::Ordering; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::io; use std::marker::PhantomData; use std::str::FromStr; use std::sync::Arc; 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::CompoundClass; use crate::Domain; use crate::SignedInteger; use crate::ValueClass; use crate::Writer; use crate::boundary as B; use crate::domain::{NoEmbeddedDomainCodec, DomainEncode, IOValueDomainCodec}; use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64}; pub type PlainValue<'a, D = IOValue> = Box + 'a>; /// Atomic values from the specification. pub trait Value { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { write_value(w, self, enc) } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static; 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_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) -> &dyn Value { panic!("Not a record") } fn is_sequence(&self) -> bool { false } fn len(&self) -> usize { panic!("Has no length") } fn index(&self, _i: usize) -> &dyn Value { panic!("Not indexable") } fn iter(&self) -> Box> + '_> { panic!("Not iterable") } fn is_set(&self) -> bool { false } fn has(&self, _v: &dyn Value) -> bool { false } fn is_dictionary(&self) -> bool { false } fn get(&self, _k: &dyn Value) -> Option<&dyn Value> { None } fn entries(&self) -> Box, &dyn Value)> + '_> { panic!("Not a dictionary") } fn is_embedded(&self) -> bool { false } fn embedded(&self) -> Cow<'_, D> { panic!("Not an embedded value") } fn annotations(&self) -> Option<&[IOValue]> { None } fn specialized(&self) -> Option<&dyn Any> { None } } pub fn value>(v: &V) -> &dyn Value { v } pub fn owned + 'static>(v: V) -> PlainValue<'static, 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 Value, f: &mut F, ) -> Result, Err> where F: FnMut(&D) -> Result, Err> { match v.value_class() { ValueClass::Atomic(a) => Ok(match a { AtomClass::Boolean => owned(v.as_boolean().unwrap()), AtomClass::Float => owned(v.as_float().unwrap()), AtomClass::Double => owned(v.as_double().unwrap()), AtomClass::SignedInteger => owned(v.as_signed_integer().unwrap()), AtomClass::String => owned(v.as_string().unwrap().into_owned()), AtomClass::ByteString => owned(Bytes(v.as_bytestring().unwrap().into_owned())), AtomClass::Symbol => owned(Symbol(v.as_symbol().unwrap().into_owned())), }), ValueClass::Compound(c) => Ok(match c { CompoundClass::Sequence => owned(v.iter().map(|w| copy_via(w, f)).collect::, _>>()?), CompoundClass::Set => owned(v.iter().map(|w| copy_via(w, f)).collect::, _>>()?), CompoundClass::Record => owned(Record::new( copy_via(v.label(), f)?, v.iter().map(|w| copy_via(w, f)).collect::, _>>()?)), CompoundClass::Dictionary => owned(v.entries().map(|(k, w)| Ok((copy_via(k, f)?, copy_via(w, f)?))) .collect::, _>>()?), }), ValueClass::Embedded => f(&v.embedded()), } } impl<'a, D: Domain + 'static> From<&'a dyn Value> for PlainValue<'static, D> { fn from(v: &'a dyn Value) -> Self { v.value_clone() } } impl<'a, D: Domain, V: Value + ?Sized> Value 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> where D: 'static { (*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) -> &dyn Value { (*self).label() } fn is_sequence(&self) -> bool { (*self).is_sequence() } fn len(&self) -> usize { (*self).len() } fn index(&self, i: usize) -> &dyn Value { (*self).index(i) } fn iter(&self) -> Box> + '_> { (*self).iter() } fn is_set(&self) -> bool { (*self).is_set() } fn has(&self, v: &dyn Value) -> bool { (*self).has(v) } fn is_dictionary(&self) -> bool { (*self).is_dictionary() } fn get<'value>(&'value self, k: &dyn Value) -> Option<&'value dyn Value> { (*self).get(k) } fn entries(&self) -> Box, &dyn Value)> + '_> { (*self).entries() } fn is_embedded(&self) -> bool { (*self).is_embedded() } fn embedded(&self) -> Cow<'_, D> { (*self).embedded() } fn annotations(&self) -> Option<&[IOValue]> { (*self).annotations() } } impl<'a, D: Domain> Value for PlainValue<'a, D> { 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> where D: 'static { 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_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) -> &dyn 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) -> &dyn 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 Value) -> bool { self.as_ref().has(v) } fn is_dictionary(&self) -> bool { self.as_ref().is_dictionary() } fn get<'value>(&'value self, k: &dyn Value) -> Option<&'value dyn Value> { self.as_ref().get(k) } fn entries(&self) -> Box, &dyn Value)> + '_> { self.as_ref().entries() } fn is_embedded(&self) -> bool { self.as_ref().is_embedded() } fn embedded(&self) -> Cow<'_, D> { self.as_ref().embedded() } fn annotations(&self) -> Option<&[IOValue]> { self.as_ref().annotations() } } impl<'a, D: Domain> Debug for dyn Value + 'a { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { TextWriter::fmt_value(f, &mut DefaultDomainCodec, self).map_err(|_| std::fmt::Error) } } impl<'a, Err: Into, D: Domain + FromStr + 'static> FromStr for PlainValue<'a, D> { type Err = io::Error; fn from_str(s: &str) -> Result { crate::annotated_from_str(s, &mut DefaultDomainCodec) } } impl<'a, D: Domain> Hash for dyn Value + 'a { fn hash(&self, state: &mut H) { match self.value_class() { ValueClass::Atomic(a) => match a { AtomClass::Boolean => self.as_boolean().unwrap().hash(state), AtomClass::Float => self.as_float().unwrap().to_bits().hash(state), AtomClass::Double => self.as_double().unwrap().to_bits().hash(state), AtomClass::SignedInteger => self.as_signed_integer().unwrap().hash(state), AtomClass::String => self.as_string().unwrap().hash(state), AtomClass::ByteString => self.as_bytestring().unwrap().hash(state), AtomClass::Symbol => self.as_symbol().unwrap().hash(state), } ValueClass::Compound(c) => match c { CompoundClass::Sequence | CompoundClass::Set => { state.write_usize(self.len()); for v in self.iter() { v.hash(state) } } CompoundClass::Record => { self.label().hash(state); state.write_usize(self.len()); for v in self.iter() { v.hash(state) } } CompoundClass::Dictionary => { state.write_usize(self.len()); for (k, v) in self.entries() { k.hash(state); v.hash(state); } } } ValueClass::Embedded => self.embedded().hash(state), } } } fn iters_eq<'a, D: Domain>( mut i1: Box> + 'a>, mut i2: Box> + 'a>, ) -> bool { loop { match i1.next() { None => return i2.next().is_none(), Some(v1) => match i2.next() { None => return false, Some(v2) => if v1 != v2 { return false; }, } } } } impl<'a, D: Domain> PartialEq for dyn Value + 'a { fn eq(&self, other: &Self) -> bool { let cls = self.value_class(); if cls != other.value_class() { return false; } match cls { ValueClass::Atomic(a) => match a { AtomClass::Boolean => self.as_boolean().unwrap() == other.as_boolean().unwrap(), AtomClass::Float => eq_f32(self.as_float().unwrap(), other.as_float().unwrap()), AtomClass::Double => eq_f64(self.as_double().unwrap(), other.as_double().unwrap()), AtomClass::SignedInteger => self.as_signed_integer().unwrap() == other.as_signed_integer().unwrap(), AtomClass::String => self.as_string().unwrap() == other.as_string().unwrap(), AtomClass::ByteString => self.as_bytestring().unwrap() == other.as_bytestring().unwrap(), AtomClass::Symbol => self.as_symbol().unwrap() == other.as_symbol().unwrap(), } ValueClass::Compound(c) => match c { CompoundClass::Record => { if self.label() != other.label() { return false; } iters_eq(self.iter(), other.iter()) } CompoundClass::Sequence => { iters_eq(self.iter(), other.iter()) } CompoundClass::Set => { let s1 = self.iter().collect::>(); let s2 = other.iter().collect::>(); s1 == s2 } CompoundClass::Dictionary => { let d1 = self.entries().collect::>(); let d2 = other.entries().collect::>(); d1 == d2 } } ValueClass::Embedded => self.embedded() == other.embedded(), } } } fn iters_cmp<'a, D: Domain>( mut i1: Box> + 'a>, mut i2: Box> + 'a>, ) -> Ordering { loop { match i1.next() { None => match i2.next() { None => return Ordering::Equal, Some(_) => return Ordering::Less, } Some(v1) => match i2.next() { None => return Ordering::Greater, Some(v2) => match v1.cmp(v2) { Ordering::Equal => (), other => return other, } } } } } impl<'a, D: Domain> Ord for dyn Value + 'a { fn cmp(&self, other: &Self) -> Ordering { let cls = self.value_class(); cls.cmp(&other.value_class()).then_with(|| match cls { ValueClass::Atomic(a) => match a { AtomClass::Boolean => self.as_boolean().cmp(&other.as_boolean()), AtomClass::Float => cmp_f32(self.as_float().unwrap(), other.as_float().unwrap()), AtomClass::Double => cmp_f64(self.as_double().unwrap(), other.as_double().unwrap()), AtomClass::SignedInteger => self.as_signed_integer().cmp(&other.as_signed_integer()), AtomClass::String => self.as_string().cmp(&other.as_string()), AtomClass::ByteString => self.as_bytestring().cmp(&other.as_bytestring()), AtomClass::Symbol => self.as_symbol().cmp(&other.as_symbol()), }, ValueClass::Compound(c) => match c { CompoundClass::Record => self.label().cmp(other.label()).then_with( || iters_cmp(self.iter(), other.iter())), CompoundClass::Sequence => iters_cmp(self.iter(), other.iter()), CompoundClass::Set => { let s1 = self.iter().collect::>(); let s2 = other.iter().collect::>(); s1.cmp(&s2) } CompoundClass::Dictionary => { let d1 = self.entries().collect::>(); let d2 = other.entries().collect::>(); d1.cmp(&d2) } }, ValueClass::Embedded => self.embedded().cmp(&other.embedded()), }) } } impl<'a, D: Domain> Eq for dyn Value + 'a {} impl<'a, D: Domain> PartialOrd for dyn Value + 'a { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } #[derive(Debug, Clone)] pub enum Atom<'a> { Boolean(bool), Float(f32), Double(f64), SignedInteger(SignedInteger), String(Cow<'a, str>), ByteString(Cow<'a, [u8]>), Symbol(Cow<'a, str>), } impl<'a> Atom<'a> { pub fn into_value(self) -> PlainValue<'static, D> { 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())), } } } 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, D: Domain> Value for Atom<'a> { fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> 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), } } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { self.clone().into_value() } fn value_class(&self) -> ValueClass { ValueClass::Atomic(self.into()) } fn as_boolean(&self) -> Option { if let Atom::Boolean(b) = self { Some(*b) } else { None } } fn as_float(&self) -> Option { if let Atom::Float(f) = self { Some(*f) } else { None } } fn as_double(&self) -> Option { 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_string(&self) -> Option> { if let Atom::String(s) = self { Some(Cow::Borrowed(s)) } else { None } } fn as_bytestring(&self) -> Option> { if let Atom::ByteString(s) = self { Some(Cow::Borrowed(s)) } else { None } } fn as_symbol(&self) -> Option> { if let Atom::Symbol(s) = self { Some(Cow::Borrowed(s)) } else { None } } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum NoValue {} impl Domain for NoValue { type Decode = NoEmbeddedDomainCodec; type Encode = NoEmbeddedDomainCodec; } impl FromStr for NoValue { type Err = io::Error; fn from_str(_s: &str) -> Result { Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) } } impl Value for NoValue { fn write(&self, _w: &mut dyn Writer, _enc: &mut dyn DomainEncode) -> io::Result<()> { unreachable!() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { unreachable!() } fn value_class(&self) -> ValueClass { unreachable!() } } impl Value 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> where D: 'static { Box::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Boolean) } fn as_boolean(&self) -> Option { Some(*self) } } impl Value 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> where D: 'static { Box::new(*self) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) } fn as_signed_integer(&self) -> Option { Some((*self).into()) } } impl Value 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> where D: 'static { Box::new(self.clone()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) } fn as_signed_integer(&self) -> Option { Some(self.clone()) } } impl Value 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> where D: 'static { Box::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) } } impl Value 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> where D: 'static { Box::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 Value for 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> where D: 'static { Box::new(self.to_owned()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) } fn as_string(&self) -> Option> { Some(Cow::Borrowed(self)) } } impl Value 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> where D: 'static { Box::new(self.clone()) } fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) } fn as_string(&self) -> Option> { Some(Cow::Borrowed(self)) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] pub struct Bytes + Debug = Vec>(T); impl + Debug> Bytes { pub fn new(t: T) -> Self { Bytes(t) } } impl + Debug, D: Domain> Value 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> where D: 'static { Box::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())) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] pub struct Symbol + Debug = String>(T); impl + Debug> Symbol { pub fn new(t: T) -> Self { Symbol(t) } } impl + Debug, D: Domain> Value 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> where D: 'static { Box::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())) } } #[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 } } impl> Value 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); w.boundary(&b)?; self.0[0].write(w, enc)?; for e in &self.0[1..] { b.shift(Some(B::Item::RecordField)); w.boundary(&b)?; e.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_record() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::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) -> &dyn Value { &self.0[0] } fn len(&self) -> usize { self.0.len() - 1 } fn index(&self, i: usize) -> &dyn Value { &self.0[i + 1] } fn iter(&self) -> Box> + '_> { Box::new(self.0[1..].iter().map(value)) } } impl> Value 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> where D: 'static { (&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) -> &dyn Value { &self[i] } fn iter(&self) -> Box> + '_> { Box::new(self[..].iter().map(value)) } } impl> Value for [V] { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_sequence()?; let mut b = B::Type::default(); for e in self { b.shift(Some(B::Item::SequenceValue)); w.boundary(&b)?; e.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_sequence() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::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) -> &dyn Value { &self[i] } fn iter(&self) -> Box> + '_> { Box::new(self[..].iter().map(value)) } } impl<'e, D: Domain, E: for<'a> Borrow> + Ord + 'e> Value 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)?; } b.shift(None); w.boundary(&b)?; w.end_set() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::new(self.iter().map(|v| Key::peel_ref(&v.borrow()).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 Value) -> bool { self.contains(&Key::wrap_ref(v)) } fn iter(&self) -> Box> + '_> { Box::new(self.iter().map(|e| Key::peel_ref(&e.borrow()))) } } // 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 Value + '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 Value + 'b) { fn borrow(&self) -> &Key<'a, D> { Key::wrap_ref(self) } } impl<'k, D: Domain, V: Value, K: for<'a> Borrow> + Ord + 'k> Value for Map { 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)?; b.shift(Some(B::Item::DictionaryValue)); w.boundary(&b)?; v.write(w, enc)?; } b.shift(None); w.boundary(&b)?; w.end_dictionary() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::new(Value::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 Value) -> bool { self.contains_key(&Key::wrap_ref(v)) } fn get(&self, k: &dyn Value) -> Option<&dyn Value> { match Map::get(self, &Key::wrap_ref(k)) { Some(v) => Some(v), None => None, } } fn entries(&self) -> Box, &dyn Value)> + '_> { Box::new(self.iter().map(|(k,v)| (Key::peel_ref(&k.borrow()), value(v)))) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(transparent)] pub struct Embedded(D); impl Embedded { pub fn new(d: D) -> Self { Embedded(d) } pub fn embedded_value(&self) -> &D { &self.0 } pub fn into_embedded_value(self) -> D { self.0 } } impl Value for Embedded { fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode) -> io::Result<()> { w.start_embedded()?; enc.encode_embedded(w, &self.0)?; w.end_embedded() } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::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) } } #[derive(Debug)] pub struct Annotations>(V, Vec, PhantomData); impl> Annotations { pub fn new(value: V, anns: Vec) -> Self { Annotations(value, anns, PhantomData) } pub fn value(&self) -> &dyn Value { &self.0 } } impl> Value 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.boundary(&b)?; self.0.write(w, enc)?; b.shift(None); w.boundary(&b)?; w.end_annotations() } else { self.0.write(w, enc) } } fn value_clone(&self) -> PlainValue<'static, D> where D: 'static { Box::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_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) -> &dyn 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) -> &dyn 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 Value) -> bool { self.value().has(v) } fn is_dictionary(&self) -> bool { self.value().is_dictionary() } fn get(&self, k: &dyn Value) -> Option<&dyn Value> { self.value().get(k) } fn entries(&self) -> Box, &dyn Value)> + '_> { self.value().entries() } fn is_embedded(&self) -> bool { self.value().is_embedded() } fn embedded(&self) -> Cow<'_, D> { self.value().embedded() } fn annotations(&self) -> Option<&[IOValue]> { Some(&self.1) } } impl> PartialEq for Annotations { fn eq(&self, other: &Self) -> bool { self.value().eq(&other.value()) } } impl> Eq for Annotations {} impl> Hash for Annotations { fn hash(&self, state: &mut H) { self.value().hash(state); } } impl> PartialOrd for Annotations { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl> Ord for Annotations { fn cmp(&self, other: &Self) -> Ordering { 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) } } 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 + 'static> FromStr for ArcValue { type Err = io::Error; fn from_str(s: &str) -> Result { Ok(arcvalue(crate::annotated_from_str(s, &mut DefaultDomainCodec)?)) } } impl FromStr for IOValue { type Err = io::Error; fn from_str(s: &str) -> Result { crate::annotated_iovalue_from_str(s) } } 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 { IOValue(b) } } impl<'a> Borrow> for IOValue { fn borrow(&self) -> &Key<'a, IOValue> { Key::wrap_ref(&*self.0.0) } } impl<'a, D: Domain> Borrow> for ArcValue { fn borrow(&self) -> &Key<'a, D> { Key::wrap_ref(&*self.0) } } impl Value 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) -> &dyn 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) -> &dyn 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 Value) -> bool { self.0.has(v) } fn is_dictionary(&self) -> bool { self.0.is_dictionary() } fn get<'value>(&'value self, k: &dyn Value) -> Option<&'value dyn Value> { self.0.get(k) } fn entries(&self) -> Box, &dyn 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<&[IOValue]> { self.0.annotations() } } impl Value 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_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) -> &dyn 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) -> &dyn 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 Value) -> bool { self.0.has(v) } fn is_dictionary(&self) -> bool { self.0.is_dictionary() } fn get<'value>(&'value self, k: &dyn Value) -> Option<&'value dyn Value> { self.0.get(k) } fn entries(&self) -> Box, &dyn Value)> + '_> { self.0.entries() } fn is_embedded(&self) -> bool { self.0.is_embedded() } fn embedded(&self) -> Cow<'_, IOValue> { self.0.embedded() } fn annotations(&self) -> Option<&[IOValue]> { self.0.annotations() } }