//! In-memory representation of Preserves `Value`s. use num::bigint::BigInt; use num::traits::cast::ToPrimitive; use std::borrow::Cow; use std::cmp::Ordering; use std::convert::From; use std::convert::TryFrom; use std::convert::TryInto; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::io; use std::ops::Index; use std::ops::IndexMut; use std::string::String; use std::sync::Arc; use std::vec::Vec; pub use std::collections::BTreeMap as Map; pub use std::collections::BTreeSet as Set; use super::signed_integer::SignedInteger; use super::text; use super::DebugDomainEncode; use super::FromStrDomainParse; use super::IOValueDomainCodec; use super::TextWriter; use super::Writer; use crate::error::{Error, ExpectedKind, Received}; /// A `Domain` implementation allows a Rust value to be placed as a Preserves [embedded /// value](https://preserves.dev/preserves.html#embeddeds) inside a Preserves term. (See also /// [Embeddable].) pub trait Domain: Sized + Debug + Eq + Hash + Ord { fn debug_encode(&self, w: &mut W) -> io::Result<()> { w.write_string(&format!("{:?}", self)) } } /// Any Rust value that implements [`Domain`] and `Clone` is automatically `Embeddable`, and /// may be placed as a Preserves [embedded /// value](https://preserves.dev/preserves.html#embeddeds) inside a Preserves term. (See also /// [Domain].) pub trait Embeddable: Domain + Clone {} impl Embeddable for T where T: Domain + Clone {} impl Domain for Arc { fn debug_encode(&self, w: &mut W) -> io::Result<()> { self.as_ref().debug_encode(w) } } /// This is the **primary programming interface** to Preserves values. The most common and /// useful implementations of this trait are first [IOValue] and second [ArcValue]. pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord { /// Every representation of Preserves values has an associated type: that of the Rust data /// able to be [embedded](https://preserves.dev/preserves.html#embeddeds) inside a value. type Embedded: Embeddable; /// `v` can be converted to a [Value]; `new` does this and then [wrap][Value::wrap]s it to /// yield an instance of [Self]. #[inline(always)] fn new(v: V) -> Self where Value: From, { Value::from(v).wrap() } /// [Embeds](https://preserves.dev/preserves.html#embeddeds) `e` to a Preserves embedded /// value; `e` is first converted to [Self::Embedded]. #[inline(always)] fn domain(e: E) -> Self where Self::Embedded: From, { Value::Embedded(e.into()).wrap() } /// Yields a Preserves `Symbol` embodying the given text, `n`. #[inline(always)] fn symbol(n: &str) -> Self { Value::symbol(n).wrap() } /// Yields a Preserves `ByteString`. #[inline(always)] fn bytestring<'a, V: Into>>(v: V) -> Self { Value::bytestring(v).wrap() } /// Attaches the given [Annotations] to the [Value]. fn wrap(anns: Annotations, v: Value) -> Self; /// Retrieves any annotations attached to `self`. fn annotations(&self) -> &Annotations; /// Retrieves the underlying [Value] represented by `self`. fn value(&self) -> &Value; /// Consumes `self`, yielding its annotations and underlying [Value]. fn pieces(self) -> (Annotations, Value); /// Consumes `self`, yielding its underlying [Value] and discarding its annotations. fn value_owned(self) -> Value; /// Retrieves the [ValueClass] of `self`. #[inline(always)] fn value_class(&self) -> ValueClass { self.value().value_class() } /// Supplies an opportunity to customize debug formatting for `self`. Defaults to writing /// `@`-prefixed annotations followed by the underlying value. fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for ann in self.annotations().slice() { write!(f, "@{:?} ", ann)?; } self.value().fmt(f) } /// Yields a deep copy of `self` with all annotations (recursively) removed. fn strip_annotations>(&self) -> M { M::wrap(Annotations::empty(), self.value().strip_annotations()) } /// Yields a deep copy of `self`, mapping embedded values to a new type via `f`. fn copy_via(&self, f: &mut F) -> Result where F: FnMut(&Self::Embedded) -> Result, Err>, { Ok(M::wrap( self.annotations().copy_via(f)?, self.value().copy_via(f)?, )) } /// Calls `f` once for each (recursively) embedded [Self::Embedded] value in `self`. fn foreach_embedded(&self, f: &mut F) -> Result<(), Err> where F: FnMut(&Self::Embedded) -> Result<(), Err>, { match &self.annotations().0 { None => (), Some(vs) => { for v in vs.iter() { v.foreach_embedded(f)? } } } self.value().foreach_embedded(f) } } /// The `Value`s from the specification. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum Value { Boolean(bool), Double(Double), SignedInteger(SignedInteger), String(String), ByteString(Vec), Symbol(String), Record(Record), Sequence(Vec), Set(Set), Dictionary(Map), Embedded(N::Embedded), } /// The kinds of `Value` from the specification. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum ValueClass { Atomic(AtomClass), Compound(CompoundClass), Embedded, } /// The kinds of `Atom` from the specification. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum AtomClass { Boolean, Double, SignedInteger, String, ByteString, Symbol, } /// The kinds of `Compound` from the specification. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum CompoundClass { Record, Sequence, Set, Dictionary, } /// Double-precision IEEE 754 Value #[derive(Clone, Copy, Debug)] pub struct Double(pub f64); /// A Record `Value`. /// /// INVARIANT: The length of the contained vector **MUST** always be non-zero. #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Record(pub Vec); impl Record { /// Retrieve the record's label. #[inline(always)] pub fn label(&self) -> &N { &self.0[0] } /// Retrieve a mutable reference to the record's label. #[inline(always)] pub fn label_mut(&mut self) -> &mut N { &mut self.0[0] } /// Retrieve the arity of the record, the number of fields it has. #[inline(always)] pub fn arity(&self) -> usize { self.0.len() - 1 } /// Retrieve a slice containing the fields of the record. #[inline(always)] pub fn fields(&self) -> &[N] { &self.0[1..] } /// Retrieve a mutable slice containing the fields of the record. #[inline(always)] pub fn fields_mut(&mut self) -> &mut [N] { &mut self.0[1..] } /// Retrieve a reference to a vector containing the record's label and fields. #[inline(always)] pub fn fields_vec(&self) -> &Vec { &self.0 } /// Retrieve a mutable reference to a vector containing the record's label and fields. #[inline(always)] pub fn fields_vec_mut(&mut self) -> &mut Vec { &mut self.0 } /// Converts `self` into a [Value]. #[inline(always)] pub fn finish(self) -> Value where N: NestedValue, { Value::Record(self) } } impl From for Double { fn from(v: f64) -> Self { Double(v) } } impl From for f64 { fn from(v: Double) -> Self { v.0 } } impl Hash for Double { fn hash(&self, state: &mut H) { self.0.to_bits().hash(state); } } impl PartialEq for Double { fn eq(&self, other: &Self) -> bool { self.0.to_bits() == other.0.to_bits() } } impl Ord for Double { fn cmp(&self, other: &Self) -> Ordering { let mut a: u64 = self.0.to_bits(); let mut b: u64 = other.0.to_bits(); if a & 0x8000_0000_0000_0000 != 0 { a ^= 0x7fff_ffff_ffff_ffff; } if b & 0x8000_0000_0000_0000 != 0 { b ^= 0x7fff_ffff_ffff_ffff; } (a as i64).cmp(&(b as i64)) } } impl PartialOrd for Double { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Eq for Double {} impl From for Value { fn from(v: bool) -> Self { Value::Boolean(v) } } impl From<&bool> for Value { fn from(v: &bool) -> Self { Value::Boolean(*v) } } impl From for Value { fn from(v: f64) -> Self { Value::Double(Double::from(v)) } } impl From<&f64> for Value { fn from(v: &f64) -> Self { Value::Double(Double::from(*v)) } } impl From<&Double> for Value { fn from(v: &Double) -> Self { Value::Double(v.clone()) } } impl From for Value { fn from(v: u8) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: i8) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: u16) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: i16) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: u32) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: i32) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: u64) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: i64) -> Self { Value::from(i128::from(v)) } } impl From for Value { fn from(v: usize) -> Self { Value::from(v as u128) } } impl From for Value { fn from(v: isize) -> Self { Value::from(v as i128) } } impl From for Value { fn from(v: u128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } } impl From for Value { fn from(v: i128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } } impl From<&BigInt> for Value { fn from(v: &BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Borrowed(v))) } } impl From for Value { fn from(v: BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Owned(v))) } } impl From<&SignedInteger> for Value { fn from(v: &SignedInteger) -> Self { Value::SignedInteger(v.clone()) } } impl From<&str> for Value { fn from(v: &str) -> Self { Value::String(String::from(v)) } } impl From for Value { fn from(v: String) -> Self { Value::String(v) } } impl From<&String> for Value { fn from(v: &String) -> Self { Value::String(v.to_owned()) } } impl From<&[u8]> for Value { fn from(v: &[u8]) -> Self { Value::ByteString(Vec::from(v)) } } // impl From> for Value { fn from(v: Vec) -> Self { Value::ByteString(v) } } impl From> for Value { fn from(v: Vec) -> Self { Value::Sequence(v) } } impl From> for Value { fn from(v: Set) -> Self { Value::Set(v) } } impl From> for Value { fn from(v: Map) -> Self { Value::Dictionary(v) } } impl Debug for Value { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { TextWriter::fmt_value(f, &mut DebugDomainEncode, self).map_err(|_| std::fmt::Error) } } impl< Err: Into, D: Embeddable + std::str::FromStr, N: NestedValue, > std::str::FromStr for Value { type Err = io::Error; fn from_str(s: &str) -> Result { Ok(text::from_str::(s, FromStrDomainParse)?.value_owned()) } } //--------------------------------------------------------------------------- impl Value { /// Converts `self` to a [NestedValue] by supplying an empty collection of annotations. pub fn wrap(self) -> N { N::wrap(Annotations::empty(), self) } /// Retrieves the [ValueClass] of `self`. fn value_class(&self) -> ValueClass { match self { Value::Boolean(_) => ValueClass::Atomic(AtomClass::Boolean), Value::Double(_) => ValueClass::Atomic(AtomClass::Double), Value::SignedInteger(_) => ValueClass::Atomic(AtomClass::SignedInteger), Value::String(_) => ValueClass::Atomic(AtomClass::String), Value::ByteString(_) => ValueClass::Atomic(AtomClass::ByteString), Value::Symbol(_) => ValueClass::Atomic(AtomClass::Symbol), Value::Record(_) => ValueClass::Compound(CompoundClass::Record), Value::Sequence(_) => ValueClass::Compound(CompoundClass::Sequence), Value::Set(_) => ValueClass::Compound(CompoundClass::Set), Value::Dictionary(_) => ValueClass::Compound(CompoundClass::Dictionary), Value::Embedded(_) => ValueClass::Embedded, } } /// Retrieve a vector of the "children" of `self`. /// /// For atoms, this is an empty vector. For records, it's all the fields (but not the /// label). For sequences and sets, it's the contained values. For dictionaries, it's all /// the values in the key-value mappings (but not the keys). pub fn children(&self) -> Vec { match self { Value::Boolean(_) | Value::Double(_) | Value::SignedInteger(_) | Value::String(_) | Value::ByteString(_) | Value::Symbol(_) | Value::Embedded(_) => vec![], Value::Record(r) => r.fields().to_vec(), Value::Sequence(vs) => vs.clone(), Value::Set(s) => s.iter().cloned().collect(), Value::Dictionary(d) => d.values().cloned().collect(), } } fn expected(&self, k: ExpectedKind) -> Error { Error::Expected( k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())), ) } /// True iff this is a [Value::Boolean]. #[inline(always)] pub fn is_boolean(&self) -> bool { self.as_boolean().is_some() } /// Yields `Some` iff this is a [Value::Boolean]. #[inline(always)] pub fn as_boolean(&self) -> Option { if let Value::Boolean(b) = self { Some(*b) } else { None } } /// Retrieve a mutable reference to the contained boolean value iff this is a [Value::Boolean]. #[inline(always)] pub fn as_boolean_mut(&mut self) -> Option<&mut bool> { if let Value::Boolean(b) = self { Some(b) } else { None } } /// Yields `Ok` iff this is a [Value::Boolean]; else [Error::Expected]. #[inline(always)] pub fn to_boolean(&self) -> Result { self.as_boolean() .ok_or_else(|| self.expected(ExpectedKind::Boolean)) } /// True iff this is a [Value::Double]. #[inline(always)] pub fn is_double(&self) -> bool { self.as_double().is_some() } /// Yields `Some` iff this is a [Value::Double]. #[inline(always)] pub fn as_double(&self) -> Option<&Double> { if let Value::Double(f) = self { Some(f) } else { None } } /// Retrieve a mutable reference to the contained [Double] value iff this is a [Value::Double]. #[inline(always)] pub fn as_double_mut(&mut self) -> Option<&mut Double> { if let Value::Double(f) = self { Some(f) } else { None } } /// Yields `Ok` iff this is a [Value::Double]; else [Error::Expected]. #[inline(always)] pub fn to_double(&self) -> Result<&Double, Error> { self.as_double() .ok_or_else(|| self.expected(ExpectedKind::Double)) } /// As [Self::is_double]. #[inline(always)] pub fn is_f64(&self) -> bool { self.is_double() } /// As [Self::as_double], but yields [f64] instead of [Double]. #[inline(always)] pub fn as_f64(&self) -> Option { self.as_double().map(|f| f.0) } /// As [Self::as_double_mut], but [f64] instead of [Double]. #[inline(always)] pub fn as_f64_mut(&mut self) -> Option<&mut f64> { self.as_double_mut().map(|f| &mut f.0) } /// As [Self::to_double], but with [f64] instead of [Double]. #[inline(always)] pub fn to_f64(&self) -> Result { self.to_double().map(|f| f.0) } /// True iff this is a [Value::SignedInteger]. #[inline(always)] pub fn is_signedinteger(&self) -> bool { self.as_signedinteger().is_some() } /// Yields `Some` iff this is a [Value::SignedInteger]. #[inline(always)] pub fn as_signedinteger(&self) -> Option<&SignedInteger> { if let Value::SignedInteger(n) = self { Some(n) } else { None } } /// Retrieve a mutable reference to the contained SignedInteger value iff this is a [Value::SignedInteger]. #[inline(always)] pub fn as_signedinteger_mut(&mut self) -> Option<&mut SignedInteger> { if let Value::SignedInteger(n) = self { Some(n) } else { None } } /// Yields `Ok` iff this is a [Value::SignedInteger]; else [Error::Expected]. #[inline(always)] pub fn to_signedinteger(&self) -> Result<&SignedInteger, Error> { self.as_signedinteger() .ok_or_else(|| self.expected(ExpectedKind::SignedInteger)) } /// True iff [Self::as_i] yields `Some`. #[inline(always)] pub fn is_i(&self) -> bool { self.as_i().is_some() } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i128]. #[inline(always)] pub fn as_i(&self) -> Option { self.as_signedinteger().and_then(|n| n.try_into().ok()) } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i128]; else [Error::Expected]. #[inline(always)] pub fn to_i(&self) -> Result { self.as_i() .ok_or_else(|| self.expected(ExpectedKind::SignedIntegerI128)) } /// True iff [Self::as_u] yields `Some`. #[inline(always)] pub fn is_u(&self) -> bool { self.as_u().is_some() } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u128]. #[inline(always)] pub fn as_u(&self) -> Option { self.as_signedinteger().and_then(|n| n.try_into().ok()) } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u128]; else [Error::Expected]. #[inline(always)] pub fn to_u(&self) -> Result { self.as_u() .ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128)) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u8]. #[inline(always)] pub fn as_u8(&self) -> Option { self.as_u().and_then(|i| i.to_u8()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i8]. #[inline(always)] pub fn as_i8(&self) -> Option { self.as_i().and_then(|i| i.to_i8()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u16]. #[inline(always)] pub fn as_u16(&self) -> Option { self.as_u().and_then(|i| i.to_u16()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i16]. #[inline(always)] pub fn as_i16(&self) -> Option { self.as_i().and_then(|i| i.to_i16()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u32]. #[inline(always)] pub fn as_u32(&self) -> Option { self.as_u().and_then(|i| i.to_u32()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i32]. #[inline(always)] pub fn as_i32(&self) -> Option { self.as_i().and_then(|i| i.to_i32()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u64]. #[inline(always)] pub fn as_u64(&self) -> Option { self.as_u().and_then(|i| i.to_u64()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i64]. #[inline(always)] pub fn as_i64(&self) -> Option { self.as_i().and_then(|i| i.to_i64()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [u128]. #[inline(always)] pub fn as_u128(&self) -> Option { self.as_u() } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [i128]. #[inline(always)] pub fn as_i128(&self) -> Option { self.as_i() } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [usize]. #[inline(always)] pub fn as_usize(&self) -> Option { self.as_u().and_then(|i| i.to_usize()) } /// Yields `Some` if `self` is a [Value::SignedInteger] that fits in [isize]. #[inline(always)] pub fn as_isize(&self) -> Option { self.as_i().and_then(|i| i.to_isize()) } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i8]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_i8(&self) -> Result { match self.as_i() { Some(i) => i .to_i8() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u8]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_u8(&self) -> Result { match self.as_u() { Some(i) => i .to_u8() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i16]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_i16(&self) -> Result { match self.as_i() { Some(i) => i .to_i16() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u16]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_u16(&self) -> Result { match self.as_u() { Some(i) => i .to_u16() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i32]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_i32(&self) -> Result { match self.as_i() { Some(i) => i .to_i32() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u32]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_u32(&self) -> Result { match self.as_u() { Some(i) => i .to_u32() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i64]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_i64(&self) -> Result { match self.as_i() { Some(i) => i .to_i64() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u64]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_u64(&self) -> Result { match self.as_u() { Some(i) => i .to_u64() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [i128]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_i128(&self) -> Result { match self.as_i() { Some(i) => i .to_i128() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [u128]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_u128(&self) -> Result { match self.as_u() { Some(i) => i .to_u128() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [isize]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_isize(&self) -> Result { match self.as_i() { Some(i) => i .to_isize() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a [Value::SignedInteger] that fits in [usize]; /// otherwise, [Error::Expected] or [Error::NumberOutOfRange]. #[inline(always)] pub fn to_usize(&self) -> Result { match self.as_u() { Some(i) => i .to_usize() .ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), None => Err(self.expected(ExpectedKind::SignedInteger)), } } /// Yields `Ok` if `self` is a record with label a symbol `UnicodeScalar` and single field /// a SignedInteger that can represent a valid Unicode scalar value. Otherwise, /// [Error::Expected] or [Error::InvalidUnicodeScalar]. otherwise, [Error::Expected] or /// [Error::NumberOutOfRange]. #[inline(always)] pub fn to_char(&self) -> Result { let fs = self.to_simple_record("UnicodeScalar", Some(1))?; let c = fs[0].value().to_u32()?; char::try_from(c).map_err(|_| Error::InvalidUnicodeScalar(c)) } /// True iff this is a [Value::String]. #[inline(always)] pub fn is_string(&self) -> bool { self.as_string().is_some() } /// Yields `Some` iff this is a [Value::String]. #[inline(always)] pub fn as_string(&self) -> Option<&String> { if let Value::String(s) = self { Some(s) } else { None } } /// Retrieve a mutable reference to the contained String value iff this is a [Value::String]. #[inline(always)] pub fn as_string_mut(&mut self) -> Option<&mut String> { if let Value::String(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a `String` iff `self` is a [Value::String]. #[inline(always)] pub fn into_string(self) -> Option { match self { Value::String(s) => Some(s), _ => None, } } /// Yields `Ok` iff this is a [Value::String]; else [Error::Expected]. #[inline(always)] pub fn to_string(&self) -> Result<&String, Error> { self.as_string() .ok_or_else(|| self.expected(ExpectedKind::String)) } /// Constructs a [Value::ByteString] from `v`. #[inline(always)] pub fn bytestring<'a, V: Into>>(v: V) -> Self { Value::ByteString(v.into().into_owned()) } /// True iff this is a [Value::ByteString]. #[inline(always)] pub fn is_bytestring(&self) -> bool { self.as_bytestring().is_some() } /// Yields `Some` iff this is a [Value::ByteString]. #[inline(always)] pub fn as_bytestring(&self) -> Option<&Vec> { if let Value::ByteString(s) = self { Some(s) } else { None } } /// Retrieve a mutable reference to the contained bytes value iff this is a [Value::ByteString]. #[inline(always)] pub fn as_bytestring_mut(&mut self) -> Option<&mut Vec> { if let Value::ByteString(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a `Vec` iff `self` is a [Value::ByteString]. #[inline(always)] pub fn into_bytestring(self) -> Option> { match self { Value::ByteString(bs) => Some(bs), _ => None, } } /// Yields `Ok` iff this is a [Value::ByteString]; else [Error::Expected]. #[inline(always)] pub fn to_bytestring(&self) -> Result<&Vec, Error> { self.as_bytestring() .ok_or_else(|| self.expected(ExpectedKind::ByteString)) } /// Constructs a [Value::Symbol] from `v`. #[inline(always)] pub fn symbol(s: &str) -> Value { Value::Symbol(s.to_string()) } /// True iff this is a [Value::Symbol]. #[inline(always)] pub fn is_symbol(&self) -> bool { self.as_symbol().is_some() } /// Yields `Some` iff this is a [Value::Symbol]. #[inline(always)] pub fn as_symbol(&self) -> Option<&String> { if let Value::Symbol(s) = self { Some(s) } else { None } } /// Retrieve a mutable reference to the contained Symbol's string iff this is a [Value::Symbol]. #[inline(always)] pub fn as_symbol_mut(&mut self) -> Option<&mut String> { if let Value::Symbol(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a `String` iff `self` is a [Value::Symbol]. #[inline(always)] pub fn into_symbol(self) -> Option { match self { Value::Symbol(s) => Some(s), _ => None, } } /// Yields `Ok` iff this is a [Value::Symbol]; else [Error::Expected]. #[inline(always)] pub fn to_symbol(&self) -> Result<&String, Error> { self.as_symbol() .ok_or_else(|| self.expected(ExpectedKind::Symbol)) } /// Constructs a record with the given label and expected arity. The new record will /// initially not have any fields, but will be allocated with capacity for `expected_arity` /// fields. #[inline(always)] pub fn record(label: N, expected_arity: usize) -> Record { let mut v = Vec::with_capacity(expected_arity + 1); v.push(label); Record(v) } /// True iff this is a [Value::Record]. #[inline(always)] pub fn is_record(&self) -> bool { matches!(*self, Value::Record(_)) } /// Yields `Some` iff this is a [Value::Record]. #[inline(always)] pub fn as_record(&self, arity: Option) -> Option<&Record> { if let Value::Record(r) = self { match arity { Some(expected) if r.arity() == expected => Some(r), Some(_other) => None, None => Some(r), } } else { None } } /// Consumes `self`, yielding a `Record` iff `self` is a [Value::Record]. #[inline(always)] pub fn into_record(self) -> Option> { match self { Value::Record(r) => Some(r), _ => None, } } /// Retrieve a mutable reference to the contained Record value iff this is a [Value::Record]. #[inline(always)] pub fn as_record_mut(&mut self, arity: Option) -> Option<&mut Record> { if let Value::Record(r) = self { match arity { Some(expected) if r.arity() == expected => Some(r), Some(_other) => None, None => Some(r), } } else { None } } /// Yields `Ok` iff this is a [Value::Record]; else [Error::Expected]. #[inline(always)] pub fn to_record(&self, arity: Option) -> Result<&Record, Error> { self.as_record(arity) .ok_or_else(|| self.expected(ExpectedKind::Record(arity))) } /// Like [Self::record], but for the common case where the label is to be a `Symbol` with a /// given text. #[inline(always)] pub fn simple_record(label: &str, expected_arity: usize) -> Record { Self::record(N::symbol(label), expected_arity) } /// Constructs a record with label a symbol with text `label`, and no fields. #[inline(always)] pub fn simple_record0(label: &str) -> Value { Self::simple_record(label, 0).finish() } /// Constructs a record with label a symbol with text `label`, and one field. #[inline(always)] pub fn simple_record1(label: &str, field: N) -> Value { let mut r = Self::simple_record(label, 1); r.fields_vec_mut().push(field); r.finish() } /// True iff `self` is a record with label a symbol with text `label` and arity matching /// `arity`: any arity, if `arity == None`, or the specific `usize` concerned otherwise. #[inline(always)] pub fn is_simple_record(&self, label: &str, arity: Option) -> bool { self.as_simple_record(label, arity).is_some() } /// Yields `Some` containing a reference to the record's fields iff /// [`Self::is_simple_record`]`(label, arity)` returns true. #[inline(always)] pub fn as_simple_record(&self, label: &str, arity: Option) -> Option<&[N]> { self.as_record(arity).and_then(|r| match r.label().value() { Value::Symbol(s) if s == label => Some(r.fields()), _ => None, }) } /// Like [Self::as_simple_record], but yields [Error::Expected] on failure. #[inline(always)] pub fn to_simple_record(&self, label: &str, arity: Option) -> Result<&[N], Error> { self.as_simple_record(label, arity) .ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity))) } /// Serde's "option" type is incoded in Preserves as `` or ``. #[inline(always)] pub fn to_option(&self) -> Result, Error> { match self.as_simple_record("None", Some(0)) { Some(_fs) => Ok(None), None => match self.as_simple_record("Some", Some(1)) { Some(fs) => Ok(Some(&fs[0])), None => Err(self.expected(ExpectedKind::Option)), }, } } /// True iff this is a [Value::Sequence]. #[inline(always)] pub fn is_sequence(&self) -> bool { self.as_sequence().is_some() } /// Yields `Some` iff this is a [Value::Sequence]. #[inline(always)] pub fn as_sequence(&self) -> Option<&Vec> { if let Value::Sequence(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a [`Vec`] iff `self` is a [Value::Sequence]. #[inline(always)] pub fn into_sequence(self) -> Option> { match self { Value::Sequence(s) => Some(s), _ => None, } } /// Retrieve a mutable reference to the contained [`Vec`] iff this is a [Value::Sequence]. #[inline(always)] pub fn as_sequence_mut(&mut self) -> Option<&mut Vec> { if let Value::Sequence(s) = self { Some(s) } else { None } } /// Yields `Ok` iff this is a [Value::Sequence]; else [Error::Expected]. #[inline(always)] pub fn to_sequence(&self) -> Result<&Vec, Error> { self.as_sequence() .ok_or_else(|| self.expected(ExpectedKind::Sequence)) } /// True iff this is a [Value::Set]. #[inline(always)] pub fn is_set(&self) -> bool { self.as_set().is_some() } /// Yields `Some` iff this is a [Value::Set]. #[inline(always)] pub fn as_set(&self) -> Option<&Set> { if let Value::Set(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a [`Set`] iff `self` is a [Value::Set]. #[inline(always)] pub fn into_set(self) -> Option> { match self { Value::Set(s) => Some(s), _ => None, } } /// Retrieve a mutable reference to the contained Set value iff this is a [Value::Set]. #[inline(always)] pub fn as_set_mut(&mut self) -> Option<&mut Set> { if let Value::Set(s) = self { Some(s) } else { None } } /// Yields `Ok` iff this is a [Value::Set]; else [Error::Expected]. #[inline(always)] pub fn to_set(&self) -> Result<&Set, Error> { self.as_set() .ok_or_else(|| self.expected(ExpectedKind::Set)) } /// True iff this is a [Value::Dictionary]. #[inline(always)] pub fn is_dictionary(&self) -> bool { self.as_dictionary().is_some() } /// Yields `Some` iff this is a [Value::Dictionary]. #[inline(always)] pub fn as_dictionary(&self) -> Option<&Map> { if let Value::Dictionary(s) = self { Some(s) } else { None } } /// Consumes `self`, yielding a [`Map`] iff `self` is a [Value::Dictionary]. #[inline(always)] pub fn into_dictionary(self) -> Option> { match self { Value::Dictionary(s) => Some(s), _ => None, } } /// Retrieve a mutable reference to the contained Map value iff this is a [Value::Dictionary]. #[inline(always)] pub fn as_dictionary_mut(&mut self) -> Option<&mut Map> { if let Value::Dictionary(s) = self { Some(s) } else { None } } /// Yields `Ok` iff this is a [Value::Dictionary]; else [Error::Expected]. #[inline(always)] pub fn to_dictionary(&self) -> Result<&Map, Error> { self.as_dictionary() .ok_or_else(|| self.expected(ExpectedKind::Dictionary)) } /// True iff this is a [Value::Embedded]. #[inline(always)] pub fn is_embedded(&self) -> bool { self.as_embedded().is_some() } /// Yields `Some` iff this is a [Value::Embedded]. #[inline(always)] pub fn as_embedded(&self) -> Option<&N::Embedded> { if let Value::Embedded(d) = self { Some(d) } else { None } } /// Yields `Ok` iff this is a [Value::Embedded]; else [Error::Expected]. #[inline(always)] pub fn to_embedded(&self) -> Result<&N::Embedded, Error> { self.as_embedded() .ok_or_else(|| self.expected(ExpectedKind::Embedded)) } /// Yields a deep copy of `self` with all annotations (recursively) removed. pub fn strip_annotations>(&self) -> Value { match self { Value::Boolean(b) => Value::Boolean(*b), Value::Double(d) => Value::Double(d.clone()), Value::SignedInteger(n) => Value::SignedInteger(n.clone()), Value::String(s) => Value::String(s.clone()), Value::ByteString(v) => Value::ByteString(v.clone()), Value::Symbol(v) => Value::Symbol(v.clone()), Value::Record(r) => Value::Record(Record( r.fields_vec() .iter() .map(|a| a.strip_annotations()) .collect(), )), Value::Sequence(v) => { Value::Sequence(v.iter().map(|a| a.strip_annotations()).collect()) } Value::Set(v) => Value::Set(v.iter().map(|a| a.strip_annotations()).collect()), Value::Dictionary(v) => Value::Dictionary( v.iter() .map(|(a, b)| (a.strip_annotations(), b.strip_annotations())) .collect(), ), Value::Embedded(d) => Value::Embedded(d.clone()), } } /// Yields a deep copy of `self`, mapping embedded values to a new type via `f`. pub fn copy_via(&self, f: &mut F) -> Result, Err> where F: FnMut(&N::Embedded) -> Result, Err>, { Ok(match self { Value::Boolean(b) => Value::Boolean(*b), Value::Double(d) => Value::Double(d.clone()), Value::SignedInteger(n) => Value::SignedInteger(n.clone()), Value::String(s) => Value::String(s.clone()), Value::ByteString(v) => Value::ByteString(v.clone()), Value::Symbol(v) => Value::Symbol(v.clone()), Value::Record(r) => Value::Record(Record( r.fields_vec() .iter() .map(|a| a.copy_via(f)) .collect::, _>>()?, )), Value::Sequence(v) => Value::Sequence( v.iter() .map(|a| a.copy_via(f)) .collect::, _>>()?, ), Value::Set(v) => Value::Set( v.iter() .map(|a| a.copy_via(f)) .collect::, _>>()?, ), Value::Dictionary(v) => Value::Dictionary( v.iter() .map(|(a, b)| Ok((a.copy_via(f)?, b.copy_via(f)?))) .collect::, _>>()?, ), Value::Embedded(d) => f(d)?, }) } /// Calls `f` once for each (recursively) embedded value in `self`. pub fn foreach_embedded(&self, f: &mut F) -> Result<(), Err> where F: FnMut(&N::Embedded) -> Result<(), Err>, { match self { Value::Boolean(_) | Value::Double(_) | Value::SignedInteger(_) | Value::String(_) | Value::ByteString(_) | Value::Symbol(_) => Ok(()), Value::Record(r) => Ok(for v in r.fields_vec() { v.foreach_embedded(f)? }), Value::Sequence(vs) => Ok(for v in vs { v.foreach_embedded(f)? }), Value::Set(vs) => Ok(for v in vs { v.foreach_embedded(f)? }), Value::Dictionary(d) => Ok(for (k, v) in d { k.foreach_embedded(f)?; v.foreach_embedded(f)?; }), Value::Embedded(d) => f(d), } } } impl Index for Value { type Output = N; #[inline(always)] fn index(&self, i: usize) -> &Self::Output { &self.as_sequence().unwrap()[i] } } impl IndexMut for Value { #[inline(always)] fn index_mut(&mut self, i: usize) -> &mut Self::Output { &mut self.as_sequence_mut().unwrap()[i] } } impl Index<&N> for Value { type Output = N; #[inline(always)] fn index(&self, i: &N) -> &Self::Output { &(*self.as_dictionary().unwrap())[i] } } //--------------------------------------------------------------------------- // This part is a terrible hack #[doc(hidden)] impl serde::Serialize for UnwrappedIOValue { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { super::magic::output_value(serializer, self.clone().wrap()) } } #[doc(hidden)] impl<'de> serde::Deserialize<'de> for UnwrappedIOValue { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { Ok(super::magic::input_value::<'de, D>(deserializer)?.value_owned()) } } //--------------------------------------------------------------------------- /// Representation of a collection of annotations to be attached to a [Value] by way of an /// implementation of trait [NestedValue]. #[derive(Clone)] pub struct Annotations( /// The complex-seeming `Option>>` is used to save memory, since a `Box` is /// smaller than a `Vec`. Option>>, ); impl Annotations { /// Yield the empty [Annotations] sequence. #[inline(always)] pub fn empty() -> Self { Annotations(None) } /// Yield [Annotations] from a vector of values. #[inline(always)] pub fn new(anns: Option>) -> Self { Annotations(anns.map(Box::new)) } /// Extract carried annotations, if there are any. #[inline(always)] pub fn maybe_slice(&self) -> Option<&[N]> { match &self.0 { None => None, Some(b) => Some(&b[..]), } } /// Extract carried annotations, supplying an empty slice if there are none. #[inline(always)] pub fn slice(&self) -> &[N] { self.maybe_slice().unwrap_or(&[]) } /// Produce a fresh [Vec] of the carried annotations. #[inline(always)] pub fn to_vec(self) -> Vec { use std::ops::DerefMut; self.0 .map(|mut b| std::mem::take(b.deref_mut())) .unwrap_or_default() } /// Allows in-place updating of the collection of carried annotations. pub fn modify(&mut self, f: F) -> &mut Self where F: FnOnce(&mut Vec), { match &mut self.0 { None => { let mut v = Vec::new(); f(&mut v); if !v.is_empty() { self.0 = Some(Box::new(v)); } } Some(b) => { use std::ops::DerefMut; f(b.deref_mut()); if b.is_empty() { self.0 = None; } } } self } /// Yields a deep copy of `self`, mapping embedded values to a new type via `f`. pub fn copy_via(&self, f: &mut F) -> Result, Err> where F: FnMut(&N::Embedded) -> Result, Err>, { Ok(match &self.0 { None => Annotations(None), Some(b) => Annotations(Some(Box::new( b.iter() .map(|a| a.copy_via(f)) .collect::, _>>()?, ))), }) } } /// A possibly-annotated Value, with annotations (themselves /// possibly-annotated) in order of appearance. #[derive(Clone)] pub struct AnnotatedValue(pub Annotations, pub Value); impl AnnotatedValue { #[inline(always)] fn new(anns: Annotations, value: Value) -> Self { AnnotatedValue(anns, value) } } impl PartialEq for AnnotatedValue { #[inline(always)] fn eq(&self, other: &Self) -> bool { self.1.eq(&other.1) } } impl Eq for AnnotatedValue {} impl Hash for AnnotatedValue { #[inline(always)] fn hash(&self, state: &mut H) { self.1.hash(state); } } impl PartialOrd for AnnotatedValue { #[inline(always)] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for AnnotatedValue { #[inline(always)] fn cmp(&self, other: &Self) -> Ordering { self.1.cmp(&other.1) } } //--------------------------------------------------------------------------- /// A simple tree representation without any reference counting. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct PlainValue(AnnotatedValue>); impl PlainValue { #[inline(always)] pub fn annotations_mut(&mut self) -> &mut Annotations { &mut (self.0).0 } #[inline(always)] pub fn value_mut(&mut self) -> &mut Value { &mut (self.0).1 } } impl NestedValue for PlainValue { type Embedded = D; #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { PlainValue(AnnotatedValue::new(anns, v)) } #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } #[inline(always)] fn pieces(self) -> (Annotations, Value) { let AnnotatedValue(anns, v) = self.0; (anns, v) } #[inline(always)] fn value_owned(self) -> Value { (self.0).1 } } impl Debug for PlainValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.debug_fmt(f) } } //--------------------------------------------------------------------------- use std::rc::Rc; /// A representation of a Preserves Value using [Rc] for reference-counting of subvalues. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct RcValue(Rc>>); impl NestedValue for RcValue { type Embedded = D; #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { RcValue(Rc::new(AnnotatedValue::new(anns, v))) } #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } #[inline(always)] fn pieces(self) -> (Annotations, Value) { match Rc::try_unwrap(self.0) { Ok(AnnotatedValue(anns, v)) => (anns, v), Err(r) => (r.0.clone(), r.1.clone()), } } #[inline(always)] fn value_owned(self) -> Value { Rc::try_unwrap(self.0) .unwrap_or_else(|_| panic!("value_owned on RcValue with refcount greater than one")) .1 } } impl Debug for RcValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.debug_fmt(f) } } //--------------------------------------------------------------------------- /// A representation of a Preserves Value using [Arc] for reference-counting of subvalues. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ArcValue(Arc>>); impl NestedValue for ArcValue { type Embedded = D; #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { ArcValue(Arc::new(AnnotatedValue::new(anns, v))) } #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } #[inline(always)] fn pieces(self) -> (Annotations, Value) { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(anns, v)) => (anns, v), Err(r) => (r.0.clone(), r.1.clone()), } } #[inline(always)] fn value_owned(self) -> Value { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(_anns, v)) => v, Err(r) => r.1.clone(), } } } impl Debug for ArcValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.debug_fmt(f) } } //--------------------------------------------------------------------------- /// A representation of a Preserves Value using [Arc] for reference-counting of subvalues and /// having [IOValue] as [NestedValue::Embedded]. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct IOValue(Arc>); pub type UnwrappedIOValue = Value; impl Domain for IOValue { fn debug_encode(&self, w: &mut W) -> io::Result<()> { w.write(&mut IOValueDomainCodec, self) } } impl NestedValue for IOValue { type Embedded = Self; #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { IOValue(Arc::new(AnnotatedValue::new(anns, v))) } #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } #[inline(always)] fn pieces(self) -> (Annotations, Value) { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(anns, v)) => (anns, v), Err(r) => (r.0.clone(), r.1.clone()), } } #[inline(always)] fn value_owned(self) -> Value { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(_anns, v)) => v, Err(r) => r.1.clone(), } } } impl Debug for IOValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.debug_fmt(f) } } impl std::str::FromStr for IOValue { type Err = io::Error; fn from_str(s: &str) -> Result { text::annotated_iovalue_from_str(s) } } impl serde::Serialize for IOValue { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { super::magic::output_value(serializer, self.clone()) } } impl<'de> serde::Deserialize<'de> for IOValue { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { super::magic::input_value(deserializer) } } //--------------------------------------------------------------------------- /// A "dummy" value that has no structure at all. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct DummyValue(AnnotatedValue>); impl Debug for DummyValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("<>") } } impl DummyValue { #[inline(always)] pub fn new() -> Self { DummyValue(AnnotatedValue::new( Annotations::empty(), Value::Boolean(false), )) } } impl NestedValue for DummyValue { type Embedded = D; #[inline(always)] fn wrap(_anns: Annotations, _v: Value) -> Self { DummyValue::new() } #[inline(always)] fn annotations(&self) -> &Annotations { &self.0 .0 } #[inline(always)] fn value(&self) -> &Value { &self.0 .1 } #[inline(always)] fn pieces(self) -> (Annotations, Value) { (self.0 .0, self.0 .1) } #[inline(always)] fn value_owned(self) -> Value { self.0 .1 } } //--------------------------------------------------------------------------- #[doc(hidden)] // https://stackoverflow.com/questions/34304593/counting-length-of-repetition-in-macro/34324856 #[macro_export] //#[allow(unused_macros)] macro_rules! count__ { () => (0usize); ( $x:tt $($xs:tt)* ) => (1usize + $crate::count__!($($xs)*)); } /// Convenience syntax for efficiently constructing Preserves /// [record][crate::value::Value::record] values. #[macro_export] macro_rules! rec { ( $label:expr $(, $item:expr)* ) => { { let mut r__ = $crate::value::Value::record($label, $crate::count__!($($item)*)); $(r__.fields_vec_mut().push($item);)* r__.finish().wrap() } } }