preserves/implementations/rust/preserves/src/repr.rs

906 lines
36 KiB
Rust

use bytemuck::TransparentWrapper;
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::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, DebugDomainCodec};
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};
#[derive(Clone, Hash, Ord, Eq, PartialOrd, PartialEq)]
#[repr(transparent)]
pub struct Value<D: Domain = IOValue>(Arc<Box<dyn ValueImpl<D>>>);
/// Atomic values from the specification.
pub trait ValueImpl<D: Domain>: 'static {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()>;
fn value_clone(&self) -> Value<D>;
fn value_class(&self) -> ValueClass;
fn as_boolean(&self) -> Option<bool> { None }
fn as_float(&self) -> Option<f32> { None }
fn as_double(&self) -> Option<f64> { None }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { None }
fn as_string(&self) -> Option<Cow<'_, str>> { None }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { None }
fn as_symbol(&self) -> Option<Cow<'_, str>> { None }
fn is_record(&self) -> bool { false }
fn label(&self) -> Value<D> { 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<dyn Iterator<Item = Value<D>> + '_> { panic!("Not iterable") }
fn is_set(&self) -> bool { false }
fn has(&self, _v: &Value<D>) -> bool { false }
fn is_dictionary(&self) -> bool { false }
fn get(&self, _k: &Value<D>) -> Option<Value<D>> { None }
fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> { panic!("Not a dictionary") }
fn as_embedded(&self) -> Option<Cow<'_, D>> { None }
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { None }
}
pub fn copy_via<D: Domain, E: Domain, F, Err>(
v: &dyn ValueImpl<D>,
f: &mut F,
) -> Result<Value<E>, Err>
where
F: FnMut(&D) -> Result<Value<E>, Err>
{
match v.value_class() {
ValueClass::Atomic(a) => Ok(match a {
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 =>
Value::new(v.iter().map(|w| copy_via(w.as_ref(), f)).collect::<Result<Vec<_>, _>>()?),
CompoundClass::Set =>
Value::new(v.iter().map(|w| copy_via(w.as_ref(), f)).collect::<Result<Set<_>, _>>()?),
CompoundClass::Record =>
Value::new(Record::new(
copy_via(v.label().as_ref(), f)?,
v.iter().map(|w| copy_via(w.as_ref(), f)).collect::<Result<Vec<_>, _>>()?)),
CompoundClass::Dictionary =>
Value::new(v.entries().map(|(k, w)| Ok((copy_via(k.as_ref(), f)?, copy_via(w.as_ref(), f)?)))
.collect::<Result<Map<_, _>, _>>()?),
}),
ValueClass::Embedded => f(&v.as_embedded().unwrap()),
}
}
// impl<'a, D: Domain, V: ValueImpl<D> + ?Sized> ValueImpl<D> for &'a V {
// fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> 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<bool> { (*self).as_boolean() }
// fn as_float(&self) -> Option<f32> { (*self).as_float() }
// fn as_double(&self) -> Option<f64> { (*self).as_double() }
// fn is_signed_integer(&self) -> bool { (*self).is_signed_integer() }
// fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { (*self).as_signed_integer() }
// fn as_string(&self) -> Option<Cow<'_, str>> { (*self).as_string() }
// fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { (*self).as_bytestring() }
// fn as_symbol(&self) -> Option<Cow<'_, str>> { (*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<dyn Iterator<Item = Value<D>> + '_> { (*self).iter() }
// fn is_set(&self) -> bool { (*self).is_set() }
// fn has(&self, v: &Value<D>) -> bool { (*self).has(v) }
// fn is_dictionary(&self) -> bool { (*self).is_dictionary() }
// fn get(&self, k: &Value<D>) -> Option<Value<D>> { (*self).get(k) }
// fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> { (*self).entries() }
// fn is_embedded(&self) -> bool { (*self).is_embedded() }
// fn embedded(&self) -> Cow<'_, D> { (*self).embedded() }
// fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { (*self).annotations() }
// }
impl<D: Domain> Value<D> {
pub fn new<V: ValueImpl<D>>(v: V) -> Self {
Value(Arc::new(Box::new(v)))
}
}
pub fn value<D: Domain, V: ValueImpl<D>>(v: V) -> Value<D> {
Value::new(v)
}
impl<D: Domain> Debug for Value<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
TextWriter::fmt_value(f, &mut DefaultDomainCodec, self).map_err(|_| std::fmt::Error)
}
}
impl<Err: Into<io::Error>, D: Domain + FromStr<Err = Err>> FromStr for Value<D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::from_str(s, &mut DebugDomainCodec)
}
}
impl<'a, D: Domain> AsRef<dyn ValueImpl<D> + 'a> for Value<D> {
fn as_ref(&self) -> &(dyn ValueImpl<D> + 'a) {
(*self.0).as_ref()
}
}
impl<D: Domain> ValueImpl<D> for Value<D> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> { self.as_ref().write(w, enc) }
fn value_clone(&self) -> Value<D> { self.as_ref().value_clone() }
fn value_class(&self) -> ValueClass { self.as_ref().value_class() }
fn as_boolean(&self) -> Option<bool> { self.as_ref().as_boolean() }
fn as_float(&self) -> Option<f32> { self.as_ref().as_float() }
fn as_double(&self) -> Option<f64> { self.as_ref().as_double() }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.as_ref().as_signed_integer() }
fn as_string(&self) -> Option<Cow<'_, str>> { self.as_ref().as_string() }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.as_ref().as_bytestring() }
fn as_symbol(&self) -> Option<Cow<'_, str>> { 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 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<dyn Iterator<Item = Value<D>> + '_> { self.as_ref().iter() }
fn is_set(&self) -> bool { self.as_ref().is_set() }
fn has(&self, v: &Value<D>) -> bool { self.as_ref().has(v) }
fn is_dictionary(&self) -> bool { self.as_ref().is_dictionary() }
fn get(&self, k: &Value<D>) -> Option<Value<D>> { self.as_ref().get(k) }
fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> { self.as_ref().entries() }
fn as_embedded(&self) -> Option<Cow<'_, D>> { self.as_ref().as_embedded() }
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { self.as_ref().annotations() }
}
impl<'a, D: Domain> Debug for dyn ValueImpl<D> + '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, D: Domain> Hash for dyn ValueImpl<D> + 'a {
fn hash<H: Hasher>(&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.as_embedded().unwrap().hash(state),
}
}
}
impl<'a, D: Domain> PartialEq for dyn ValueImpl<D> + '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; }
self.iter().eq(other.iter())
}
CompoundClass::Sequence => {
self.iter().eq(other.iter())
}
CompoundClass::Set => {
let s1 = self.iter().collect::<Set<_>>();
let s2 = other.iter().collect::<Set<_>>();
s1 == s2
}
CompoundClass::Dictionary => {
let d1 = self.entries().collect::<Map<_, _>>();
let d2 = other.entries().collect::<Map<_, _>>();
d1 == d2
}
}
ValueClass::Embedded => self.as_embedded().unwrap() == other.as_embedded().unwrap(),
}
}
}
impl<'a, D: Domain> Ord for dyn ValueImpl<D> + '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().unwrap().cmp(&other.as_signed_integer().unwrap()),
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(
|| self.iter().cmp(other.iter())),
CompoundClass::Sequence => self.iter().cmp(other.iter()),
CompoundClass::Set => {
let s1 = self.iter().collect::<Set<_>>();
let s2 = other.iter().collect::<Set<_>>();
s1.cmp(&s2)
}
CompoundClass::Dictionary => {
let d1 = self.entries().collect::<Map<_, _>>();
let d2 = other.entries().collect::<Map<_, _>>();
d1.cmp(&d2)
}
},
ValueClass::Embedded => self.as_embedded().unwrap().cmp(&other.as_embedded().unwrap()),
})
}
}
impl<'a, D: Domain> Eq for dyn ValueImpl<D> + 'a {}
impl<'a, D: Domain> PartialOrd for dyn ValueImpl<D> + 'a {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[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_value<D: Domain>(self) -> Value<D> {
match self {
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<bool> for Atom<'a> { fn from(v: bool) -> Self { Atom::Boolean(v) } }
impl<'a> From<f32> for Atom<'a> { fn from(v: f32) -> Self { Atom::Float(v) } }
impl<'a> From<f64> 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<SignedInteger> 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<String> 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<Vec<u8>> for Atom<'a> { fn from(v: Vec<u8>) -> Self { Atom::ByteString(Cow::Owned(v)) } }
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> ValueImpl<D> for Atom<'a> {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> 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) -> Value<D> {
self.clone().into_value()
}
fn value_class(&self) -> ValueClass {
ValueClass::Atomic(self.into())
}
fn as_boolean(&self) -> Option<bool> {
if let Atom::Boolean(b) = self { Some(*b) } else { None }
}
fn as_float(&self) -> Option<f32> {
if let Atom::Float(f) = self { Some(*f) } else { None }
}
fn as_double(&self) -> Option<f64> {
if let Atom::Double(d) = self { Some(*d) } else { None }
}
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
if let Atom::SignedInteger(i) = self { Some(Cow::Borrowed(i)) } else { None }
}
fn as_string(&self) -> Option<Cow<'_, str>> {
if let Atom::String(s) = self { Some(Cow::Borrowed(s)) } else { None }
}
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> {
if let Atom::ByteString(s) = self { Some(Cow::Borrowed(s)) } else { None }
}
fn as_symbol(&self) -> Option<Cow<'_, str>> {
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<Self, Self::Err> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
}
}
impl<D: Domain> ValueImpl<D> for NoValue {
fn write(&self, _w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { unreachable!() }
fn value_clone(&self) -> Value<D> { unreachable!() }
fn value_class(&self) -> ValueClass { unreachable!() }
}
impl<D: Domain> ValueImpl<D> for bool {
fn write(&self, w: &mut dyn Writer, __enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_bool(*self) }
fn value_clone(&self) -> Value<D> { Value::new(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Boolean) }
fn as_boolean(&self) -> Option<bool> { Some(*self) }
}
impl<D: Domain> ValueImpl<D> for u64 {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_u64(*self) }
fn value_clone(&self) -> Value<D> { Value::new(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
Some(Cow::Owned(SignedInteger::from(*self)))
}
}
impl<D: Domain> ValueImpl<D> for SignedInteger {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_signed_integer(self) }
fn value_clone(&self) -> Value<D> { Value::new(self.clone()) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
Some(Cow::Borrowed(self))
}
}
impl<D: Domain> ValueImpl<D> for f32 {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_f32(*self) }
fn value_clone(&self) -> Value<D> { Value::new(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Float) }
fn as_float(&self) -> Option<f32> { Some(*self) }
fn as_double(&self) -> Option<f64> { Some(*self as f64) }
}
impl<D: Domain> ValueImpl<D> for f64 {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_f64(*self) }
fn value_clone(&self) -> Value<D> { Value::new(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Float) }
fn as_float(&self) -> Option<f32> { Some(*self as f32) }
fn as_double(&self) -> Option<f64> { Some(*self) }
}
impl<'a, D: Domain> ValueImpl<D> for &'a str {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_string(self) }
fn value_clone(&self) -> Value<D> { Value::new(self.to_owned()) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) }
fn as_string(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self)) }
}
impl<D: Domain> ValueImpl<D> for String {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_string(self) }
fn value_clone(&self) -> Value<D> { Value::new(self.clone()) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) }
fn as_string(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self)) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Bytes<T: AsRef<[u8]> + Debug = Vec<u8>>(T);
impl<T: AsRef<[u8]> + Debug> Bytes<T> {
pub fn new(t: T) -> Self {
Bytes(t)
}
}
impl<T: AsRef<[u8]> + Debug + 'static, D: Domain> ValueImpl<D> for Bytes<T> {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_bytes(self.0.as_ref()) }
fn value_clone(&self) -> Value<D> { Value::new(Bytes(self.0.as_ref().to_owned())) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::ByteString) }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { Some(Cow::Borrowed(self.0.as_ref())) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Symbol<T: AsRef<str> + Debug = String>(T);
impl<T: AsRef<str> + Debug> Symbol<T> {
pub fn new(t: T) -> Self {
Symbol(t)
}
}
impl<T: AsRef<str> + Debug + 'static, D: Domain> ValueImpl<D> for Symbol<T> {
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_symbol(self.0.as_ref()) }
fn value_clone(&self) -> Value<D> { Value::new(Symbol(self.0.as_ref().to_owned())) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Symbol) }
fn as_symbol(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self.0.as_ref())) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Record<V>(Vec<V> /* at least one element, for the label */);
impl<V> Record<V> {
pub fn new(label: V, mut fields: Vec<V>) -> Self {
fields.insert(0, label);
Record(fields)
}
pub fn _from_vec(v: Vec<V>) -> Self {
if v.is_empty() { panic!("Internal error: empty vec supplied to Record::_from_vec") }
Record(v)
}
pub fn _vec(&self) -> &Vec<V> {
&self.0
}
}
impl<D: Domain> ValueImpl<D> for Record<Value<D>> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> 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) -> Value<D> {
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> { self.0[0].clone() }
fn len(&self) -> usize { self.0.len() - 1 }
fn index(&self, i: usize) -> Value<D> { self.0[i + 1].clone() }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self.0[1..].iter().cloned())
}
}
impl<D: Domain> ValueImpl<D> for Vec<Value<D>> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> {
(&self[..]).write(w, enc)
}
fn value_clone(&self) -> Value<D> {
(&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> { self[i].clone() }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self[..].iter().cloned())
}
}
impl<D: Domain> ValueImpl<D> for [Value<D>] {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> 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) -> Value<D> {
Value::new(self.iter().map(|v| v.value_clone()).collect::<Vec<_>>())
}
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> { self[i].clone() }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self[..].iter().cloned())
}
}
impl<D: Domain> ValueImpl<D> for Set<Value<D>> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> {
w.start_set()?;
let mut b = B::Type::default();
for e in self {
b.shift(Some(B::Item::SetValue));
w.boundary(&b)?;
e.write(w, enc)?;
}
b.shift(None);
w.boundary(&b)?;
w.end_set()
}
fn value_clone(&self) -> Value<D> {
Value::new(self.iter().map(|v| v.value_clone()).collect::<Set<_>>())
}
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: &Value<D>) -> bool { self.contains(v) }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self.iter().map(|v| v.value_clone()))
}
}
impl<D: Domain> ValueImpl<D> for Map<Value<D>, Value<D>> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> 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)?;
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()
}
fn value_clone(&self) -> Value<D> {
Value::new(ValueImpl::entries(self).map(|(k, v)| (k.value_clone(), v.value_clone())).collect::<Map<_, _>>())
}
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: &Value<D>) -> bool { self.contains_key(v) }
fn get(&self, k: &Value<D>) -> Option<Value<D>> {
Map::get(self, &k).map(Value::clone)
}
fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> {
Box::new(self.iter().map(|(k,v)| (k.clone(), v.clone())))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Embedded<D: Domain>(D);
impl<D: Domain> Embedded<D> {
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<D: Domain> ValueImpl<D> for Embedded<D> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> {
w.start_embedded()?;
enc.encode_embedded(w, &self.0)?;
w.end_embedded()
}
fn value_clone(&self) -> Value<D> { Value::new(self.clone()) }
fn value_class(&self) -> ValueClass { ValueClass::Embedded }
fn as_embedded(&self) -> Option<Cow<'_, D>> { Some(Cow::Borrowed(&self.0)) }
}
#[derive(Debug)]
pub struct Annotations<D: Domain, V: ValueImpl<D> + 'static>(V, Vec<IOValue>, PhantomData<D>);
impl<D: Domain, V: ValueImpl<D>> Annotations<D, V> {
pub fn new(value: V, anns: Vec<IOValue>) -> Value<D> {
if anns.is_empty() {
Value::new(value)
} else {
Value::new(Annotations(value, anns, PhantomData))
}
}
pub fn value(&self) -> &dyn ValueImpl<D> {
&self.0
}
}
impl<D: Domain, V: ValueImpl<D>> ValueImpl<D> for Annotations<D, V> {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> {
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()
}
fn value_clone(&self) -> Value<D> {
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<bool> { self.value().as_boolean() }
fn as_float(&self) -> Option<f32> { self.value().as_float() }
fn as_double(&self) -> Option<f64> { self.value().as_double() }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.value().as_signed_integer() }
fn as_string(&self) -> Option<Cow<'_, str>> { self.value().as_string() }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.value().as_bytestring() }
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.value().as_symbol() }
fn is_record(&self) -> bool { self.value().is_record() }
fn label(&self) -> Value<D> { 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<dyn Iterator<Item = Value<D>> + '_> { self.value().iter() }
fn is_set(&self) -> bool { self.value().is_set() }
fn has(&self, v: &Value<D>) -> bool { self.value().has(v) }
fn is_dictionary(&self) -> bool { self.value().is_dictionary() }
fn get(&self, k: &Value<D>) -> Option<Value<D>> { self.value().get(k) }
fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> { self.value().entries() }
fn as_embedded(&self) -> Option<Cow<'_, D>> { self.value().as_embedded() }
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { Some(Cow::Borrowed(&self.1)) }
}
impl<D: Domain, V: ValueImpl<D>> PartialEq for Annotations<D, V> {
fn eq(&self, other: &Self) -> bool {
self.value().eq(other.value())
}
}
impl<D: Domain, V: ValueImpl<D>> Eq for Annotations<D, V> {}
impl<D: Domain, V: ValueImpl<D>> Hash for Annotations<D, V> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value().hash(state);
}
}
impl<D: Domain, V: ValueImpl<D>> PartialOrd for Annotations<D, V> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<D: Domain, V: ValueImpl<D>> Ord for Annotations<D, V> {
fn cmp(&self, other: &Self) -> Ordering {
self.value().cmp(other.value())
}
}
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct IOValue(Value<IOValue>);
unsafe impl TransparentWrapper<Value<IOValue>> for IOValue {}
impl Debug for IOValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl FromStr for IOValue {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::annotated_iovalue_from_str(s)
}
}
impl From<Value<IOValue>> for IOValue {
fn from(b: Value<IOValue>) -> Self {
IOValue(b)
}
}
impl From<IOValue> for Value<IOValue> {
fn from(b: IOValue) -> Self {
b.0
}
}
impl<D: Domain, V: ValueImpl<D>> From<Vec<V>> for Value<D> {
fn from(v: Vec<V>) -> Self {
value(v.into_iter().map(value).collect::<Vec<_>>())
}
}
impl<'a> From<&'a Value<IOValue>> for &'a IOValue {
fn from(b: &'a Value<IOValue>) -> Self {
IOValue::wrap_ref(b)
}
}
impl<'a> From<&'a IOValue> for &'a Value<IOValue> {
fn from(b: &'a IOValue) -> Self {
IOValue::peel_ref(b)
}
}
// impl<D: Domain> ValueImpl<D> for ArcValue<D> {
// fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> { self.0.write(w, enc) }
// fn value_clone(&self) -> Value<D> { Value::new(self.clone()) }
// fn value_class(&self) -> ValueClass { self.0.value_class() }
// fn as_boolean(&self) -> Option<bool> { self.0.as_boolean() }
// fn as_float(&self) -> Option<f32> { self.0.as_float() }
// fn as_double(&self) -> Option<f64> { self.0.as_double() }
// fn is_signed_integer(&self) -> bool { self.0.is_signed_integer() }
// fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.0.as_signed_integer() }
// fn as_string(&self) -> Option<Cow<'_, str>> { self.0.as_string() }
// fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.0.as_bytestring() }
// fn as_symbol(&self) -> Option<Cow<'_, str>> { 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<dyn Iterator<Item = Value<D>> + '_> { self.0.iter() }
// fn is_set(&self) -> bool { self.0.is_set() }
// fn has(&self, v: &Value<D>) -> bool { self.0.has(v) }
// fn is_dictionary(&self) -> bool { self.0.is_dictionary() }
// fn get(&self, k: &Value<D>) -> Option<Value<D>> { self.0.get(k) }
// fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, 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<Cow<'_, [IOValue]>> { self.0.annotations() }
// }
impl ValueImpl<IOValue> for IOValue {
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<IOValue>) -> io::Result<()> { self.0.write(w, enc) }
fn value_clone(&self) -> Value<IOValue> { Value::new(self.clone()) }
fn value_class(&self) -> ValueClass { self.0.value_class() }
fn as_boolean(&self) -> Option<bool> { self.0.as_boolean() }
fn as_float(&self) -> Option<f32> { self.0.as_float() }
fn as_double(&self) -> Option<f64> { self.0.as_double() }
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.0.as_signed_integer() }
fn as_string(&self) -> Option<Cow<'_, str>> { self.0.as_string() }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.0.as_bytestring() }
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.0.as_symbol() }
fn is_record(&self) -> bool { self.0.is_record() }
fn label(&self) -> Value<IOValue> { 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<dyn Iterator<Item = Value<IOValue>> + '_> { self.0.iter() }
fn is_set(&self) -> bool { self.0.is_set() }
fn has(&self, v: &Value<IOValue>) -> bool { self.0.has(v) }
fn is_dictionary(&self) -> bool { self.0.is_dictionary() }
fn get(&self, k: &Value<IOValue>) -> Option<Value<IOValue>> { self.0.get(k) }
fn entries(&self) -> Box<dyn Iterator<Item = (Value<IOValue>, Value<IOValue>)> + '_> { self.0.entries() }
fn as_embedded(&self) -> Option<Cow<'_, IOValue>> { self.0.as_embedded() }
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { self.0.annotations() }
}