use std::borrow::Borrow;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt::Debug;
use std::hash::Hash;
use std::hash::Hasher;
use std::io;
use std::ops::Deref;
use crate::Atom;
use crate::AtomClass;
use crate::CompoundClass;
use crate::Domain;
use crate::DomainDecode;
use crate::DomainEncode;
use crate::IOValue;
use crate::IOValueDomainDecode;
use crate::IOValueDomainEncode;
use crate::IOValueReader;
use crate::Reader;
use crate::SignedInteger;
use crate::Value;
use crate::ValueClass;
use crate::ValueImpl;
use crate::ValueReader;
use crate::Writer;
use crate::boundary as B;
use crate::error::SyntaxError;
use crate::reader::ReaderResult;
pub use std::collections::BTreeSet as Set;
pub use std::collections::BTreeMap as Map;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Bytes<T: AsRef<[u8]> + Clone + Debug = Vec<u8>>(T);
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Embedded<D: Domain>(D);
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Symbol<T: AsRef<str> + Clone + Debug = String>(T);
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Record<V>(Vec<V> );
#[derive(Clone)]
pub struct Annotations<D: Domain>(Value<D>, Vec<IOValue>);
pub struct TreeValueReader;
impl<D: Domain> ValueImpl<D> for bool {
fn owned_value(&self) -> Value<D> { Value::new(*self) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_bool(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Boolean) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::Boolean(*self)) }
fn as_boolean(&self) -> Option<bool> { Some(*self) }
}
macro_rules! value_impl_integer_type {
($t:ty, $write_method:ident) => {
impl<D: Domain> ValueImpl<D> for $t {
fn owned_value(&self) -> Value<D> { Value::new(*self) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.$write_method(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
fn as_atom(&self) -> Option<Atom<'_>> {
Some(Atom::SignedInteger(Cow::Owned(SignedInteger::from(*self))))
}
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
Some(Cow::Owned(SignedInteger::from(*self)))
}
}
}
}
value_impl_integer_type!(i8, write_i8);
value_impl_integer_type!(u8, write_u8);
value_impl_integer_type!(i16, write_i16);
value_impl_integer_type!(u16, write_u16);
value_impl_integer_type!(i32, write_i32);
value_impl_integer_type!(u32, write_u32);
value_impl_integer_type!(i64, write_i64);
value_impl_integer_type!(u64, write_u64);
value_impl_integer_type!(i128, write_i128);
value_impl_integer_type!(u128, write_u128);
value_impl_integer_type!(isize, write_isize);
value_impl_integer_type!(usize, write_usize);
impl<D: Domain> ValueImpl<D> for SignedInteger {
fn owned_value(&self) -> Value<D> { Value::new(self.clone()) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_signed_integer(self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
fn as_atom(&self) -> Option<Atom<'_>> {
Some(Atom::SignedInteger(Cow::Borrowed(self)))
}
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
Some(Cow::Borrowed(self))
}
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Double(pub f64);
impl Double {
pub fn new(value: f64) -> Self {
Self(value)
}
}
impl From<f64> for Double {
fn from(value: f64) -> Self {
Double(value)
}
}
impl From<Double> for f64 {
fn from(value: Double) -> Self {
value.0
}
}
impl<D: Domain> ValueImpl<D> for Double {
fn owned_value(&self) -> Value<D> { Value::new(self.0) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_f64(self.0) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Double) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::Double(self.0)) }
fn as_double(&self) -> Option<f64> { Some(self.0) }
}
impl<D: Domain> ValueImpl<D> for f64 {
fn owned_value(&self) -> Value<D> { Value::new(*self) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_f64(*self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Double) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::Double(*self)) }
fn as_double(&self) -> Option<f64> { Some(*self) }
}
impl<D: Domain> ValueImpl<D> for &'static str {
fn owned_value(&self) -> Value<D> { Value::new(self.to_string()) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_string(self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::String(Cow::Borrowed(self))) }
fn as_string(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self)) }
}
impl<D: Domain> ValueImpl<D> for String {
fn owned_value(&self) -> Value<D> { Value::new(self.clone()) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_string(self) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::String) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::String(Cow::Borrowed(self))) }
fn as_string(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self)) }
}
impl<T: AsRef<[u8]> + Clone + Debug> Bytes<T> {
pub fn new(t: T) -> Self {
Bytes(t)
}
pub fn inner(&self) -> &T {
&self.0
}
pub fn unwrap(self) -> T {
self.0
}
}
impl From<Vec<u8>> for Bytes {
fn from(value: Vec<u8>) -> Self {
Bytes::new(value)
}
}
impl<T: AsRef<[u8]> + Clone + Debug + Sync + Send + 'static, D: Domain> ValueImpl<D> for Bytes<T> {
fn owned_value(&self) -> Value<D> { Value::new(Bytes(self.0.as_ref().to_vec())) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_bytes(self.0.as_ref()) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::ByteString) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::ByteString(Cow::Borrowed(self.0.as_ref()))) }
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { Some(Cow::Borrowed(self.0.as_ref())) }
}
impl<T: AsRef<str> + Clone + Debug> Symbol<T> {
pub fn new(t: T) -> Self {
Symbol(t)
}
pub fn inner(&self) -> &T {
&self.0
}
pub fn unwrap(self) -> T {
self.0
}
}
impl<T: AsRef<str> + Clone + Debug> From<T> for Symbol<T> {
fn from(value: T) -> Self {
Symbol(value)
}
}
impl<T: AsRef<str> + Clone + Debug> AsRef<str> for Symbol<T> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<'a> From<&'a str> for Symbol<String> {
fn from(value: &'a str) -> Self {
Symbol(value.to_string())
}
}
impl<T: AsRef<str> + Clone + Debug + Sync + Send + 'static, D: Domain> ValueImpl<D> for Symbol<T> {
fn owned_value(&self) -> Value<D> { Value::new(Symbol(self.0.as_ref().to_string())) }
fn write(&self, w: &mut dyn Writer, _enc: &mut dyn DomainEncode<D>) -> io::Result<()> { w.write_symbol(self.0.as_ref()) }
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Symbol) }
fn as_atom(&self) -> Option<Atom<'_>> { Some(Atom::Symbol(Cow::Borrowed(self.0.as_ref()))) }
fn as_symbol(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self.0.as_ref())) }
}
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
}
pub fn _vec_mut(&mut self) -> &mut Vec<V> {
&mut self.0
}
pub fn _into_vec(self) -> Vec<V> {
self.0
}
pub fn fields_iter(&self) -> impl Iterator<Item = &V> + '_ {
let mut i = self.0.iter();
i.next(); i
}
}
impl<V> std::ops::Index<usize> for Record<V> {
type Output = V;
fn index(&self, index: usize) -> &Self::Output {
self.0.index(index + 1)
}
}
impl<V> std::ops::IndexMut<usize> for Record<V> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.0.index_mut(index + 1)
}
}
impl<D: Domain> ValueImpl<D> for Record<Value<D>> {
fn owned_value(&self) -> Value<D> {
Value::new(Record(self.0.clone()))
}
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_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Record) }
fn is_record(&self) -> bool { true }
fn label(&self) -> Value<D> { self.0[0].clone() }
fn collect_record(&self) -> Option<Cow<'_, Record<Value<D>>>> {
Some(Cow::Borrowed(self))
}
fn collect_simple_record(&self, name: &str, arity: Option<usize>) -> Option<Cow<'_, Record<Value<D>>>> {
self.is_simple_record(name, arity).then(|| Cow::Borrowed(self))
}
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())
}
fn as_atom(&self) -> Option<Atom<'_>> { None }
}
impl<D: Domain, V: ValueImpl<D> + Sync + Send + 'static> ValueImpl<D> for Vec<V> {
fn owned_value(&self) -> Value<D> {
Value::new(self.iter().map(|v| v.owned_value()).collect::<Vec<_>>())
}
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.iter() {
b.shift(Some(B::Item::SequenceValue));
w.boundary(&b)?;
e.write(w, enc)?;
}
b.shift(None);
w.boundary(&b)?;
w.end_sequence()
}
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].owned_value() }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self[..].iter().map(|v| v.owned_value()))
}
fn as_atom(&self) -> Option<Atom<'_>> { None }
}
impl<D: Domain, E: Borrow<Value<D>> + Ord + Sync + Send + 'static> ValueImpl<D> for Set<E> {
fn owned_value(&self) -> Value<D> {
Value::new(ValueImpl::iter(self).collect::<Set<_>>())
}
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.borrow().write(w, enc)?;
}
b.shift(None);
w.boundary(&b)?;
w.end_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.borrow().owned_value()))
}
fn as_atom(&self) -> Option<Atom<'_>> { None }
}
impl<D: Domain, K: Borrow<Value<D>> + Ord + Sync + Send + 'static, V: ValueImpl<D> + Sync + Send + 'static> ValueImpl<D> for Map<K, V> {
fn owned_value(&self) -> Value<D> {
Value::new(self.entries().collect::<Map<_,_>>())
}
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.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_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Dictionary) }
fn is_dictionary(&self) -> bool { true }
fn len(&self) -> usize { self.len() }
fn iter(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self.values().map(|v| v.borrow().owned_value()))
}
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(|v| v.owned_value()) }
fn entries(&self) -> Box<dyn Iterator<Item = (Value<D>, Value<D>)> + '_> {
Box::new(self.iter().map(|(k,v)| (k.borrow().owned_value(), v.owned_value())))
}
fn keys(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> {
Box::new(self.keys().map(|k| k.borrow().owned_value()))
}
fn as_atom(&self) -> Option<Atom<'_>> { None }
}
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> From<D> for Embedded<D> {
fn from(value: D) -> Self {
Embedded::new(value)
}
}
impl<D: Domain> ValueImpl<D> for Embedded<D> {
fn owned_value(&self) -> Value<D> { Value::new(self.clone()) }
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_class(&self) -> ValueClass { ValueClass::Embedded }
fn as_embedded(&self) -> Option<Cow<'_, D>> { Some(Cow::Borrowed(&self.0)) }
fn as_atom(&self) -> Option<Atom<'_>> { None }
}
impl<D: Domain> Annotations<D> {
pub fn new(value: Value<D>, anns: Vec<IOValue>) -> Self {
Annotations(value, anns)
}
pub fn value(&self) -> &Value<D> {
&self.0
}
}
impl<D: Domain> ValueImpl<D> for Annotations<D> {
fn owned_value(&self) -> Value<D> { Value::new(self.clone()) }
fn write(&self, w: &mut dyn Writer, enc: &mut dyn DomainEncode<D>) -> io::Result<()> {
if !self.1.is_empty() && w.should_write_annotations() {
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 IOValueDomainEncode)?;
}
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_class(&self) -> ValueClass { self.value().value_class() }
fn as_atom(&self) -> Option<Atom<'_>> { self.value().as_atom() }
fn as_boolean(&self) -> Option<bool> { self.value().as_boolean() }
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 keys(&self) -> Box<dyn Iterator<Item = Value<D>> + '_> { self.value().keys() }
fn as_embedded(&self) -> Option<Cow<'_, D>> { self.value().as_embedded() }
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { Some(Cow::Borrowed(&self.1)) }
fn inner_peeled(&self) -> Option<Value<D>> { Some(self.0.clone()) }
}
impl<D: Domain> Hash for Annotations<D> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.deref().hash(state)
}
}
impl<D: Domain> PartialEq for Annotations<D> {
fn eq(&self, other: &Self) -> bool {
self.0.deref().eq(other.0.deref())
}
}
impl<D: Domain> Ord for Annotations<D> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.deref().cmp(other.0.deref())
}
}
impl<D: Domain> Eq for Annotations<D> {}
impl<D: Domain> PartialOrd for Annotations<D> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub fn read<'de, R: Reader<'de> + ?Sized, D: Domain, Dec: DomainDecode<D>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>> {
let (anns, v) = match read_annotations {
true => TreeValueReader::gather_annotations(r)?.ok_or_else(|| r.wrap_syntax_error(SyntaxError::eof()))?,
false => (Vec::new(), r.skip_annotations()?.ok_or_else(|| r.wrap_syntax_error(SyntaxError::eof()))?),
};
let value: Value<D> = match v {
ValueClass::Atomic(a) => match a {
AtomClass::Boolean => Value::new(r.next_boolean()?),
AtomClass::Double => Value::new(r.next_double()?),
AtomClass::SignedInteger => Value::new(r.next_signedinteger()?.into_owned()),
AtomClass::String => Value::new(r.next_str()?.into_owned()),
AtomClass::ByteString => Value::new(Bytes(r.next_bytestring()?.into_owned())),
AtomClass::Symbol => Value::new(Symbol(r.next_symbol()?.into_owned())),
},
ValueClass::Embedded => {
r.open_embedded()?;
let v = dec.decode_embedded::<R, TreeValueReader>(r, read_annotations)?;
r.close_embedded()?;
Value::new(Embedded(v))
}
ValueClass::Compound(CompoundClass::Record) => {
let mut vs = Vec::new();
r.open_record()?;
let mut b = B::start(B::Item::RecordLabel);
r.boundary(&b)?;
vs.push(read(r, read_annotations, dec)?);
while !r.close_compound(&mut b, &B::Item::RecordField)? {
vs.push(read(r, read_annotations, dec)?);
}
Value::new(Record::_from_vec(vs))
}
ValueClass::Compound(CompoundClass::Sequence) => {
let mut vs = Vec::new();
r.open_sequence()?;
let mut b = B::Type::default();
while !r.close_compound(&mut b, &B::Item::SequenceValue)? {
vs.push(read(r, read_annotations, dec)?);
}
Value::new(vs)
}
ValueClass::Compound(CompoundClass::Set) => {
let mut s = Set::new();
r.open_set()?;
let mut b = B::Type::default();
while !r.close_compound(&mut b, &B::Item::SetValue)? {
let v_mark = r.mark()?;
if !s.insert(read(r, read_annotations, dec)?) {
Err(SyntaxError::new(Some(v_mark), "Duplicate set element"))?;
}
}
Value::new(s)
}
ValueClass::Compound(CompoundClass::Dictionary) => {
let mut d = Map::new();
r.open_dictionary()?;
let mut b = B::Type::default();
while !r.close_compound(&mut b, &B::Item::DictionaryKey)? {
let k_mark = r.mark()?;
let k = read(r, read_annotations, dec)?;
b.shift(Some(B::Item::DictionaryValue));
r.boundary(&b)?;
if d.insert(k, read(r, read_annotations, dec)?).is_some() {
Err(SyntaxError::new(Some(k_mark), "Duplicate key"))?;
}
}
Value::new(d)
}
};
if anns.is_empty() {
Ok(value)
} else {
Ok(Value::new(Annotations::new(value, anns)))
}
}
impl<D: Domain> ValueReader<D> for TreeValueReader {
fn read<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<D>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>> {
Ok(read(r, read_annotations, dec)?)
}
}
impl IOValueReader for TreeValueReader {
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
r: &mut R,
read_annotations: bool,
) -> ReaderResult<IOValue> {
Self::read(r, read_annotations, &mut IOValueDomainDecode).map(|v| v.into())
}
}