ArcValue, more tests

This commit is contained in:
Tony Garnock-Jones 2022-11-04 16:04:19 +01:00
parent 259a3c8ead
commit 0d1522d869
4 changed files with 130 additions and 20 deletions

View File

@ -21,6 +21,7 @@ pub use packed::from_bytes;
pub use packed::iovalue_from_bytes;
pub use reader::Reader;
pub use repr::Annotations;
pub use repr::ArcValue;
pub use repr::Atom;
pub use repr::Bytes;
pub use repr::Embedded;

View File

@ -12,13 +12,13 @@ use crate::BytesBinarySource;
use crate::Domain;
use crate::DomainDecode;
use crate::IOValue;
use crate::PlainValue;
use crate::Reader;
use crate::Value;
pub fn from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<Box<dyn Value<D>>> {
) -> io::Result<PlainValue<'static, D>> {
BytesBinarySource::new(bs).packed().next(false, decode_embedded)
}
@ -29,7 +29,7 @@ pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
pub fn annotated_from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<Box<dyn Value<D>>> {
) -> io::Result<PlainValue<'static, D>> {
super::BytesBinarySource::new(bs).packed().next(true, decode_embedded)
}

View File

@ -26,7 +26,6 @@ use crate::domain::{NoEmbeddedDomainCodec, DomainEncode, IOValueDomainCodec};
use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64};
pub type PlainValue<'a, D = IOValue> = Box<dyn Value<D> + 'a>;
pub type ArcValue<D = IOValue> = Arc<dyn Value<D>>;
/// Atomic values from the specification.
pub trait Value<D: Domain> {
@ -79,8 +78,12 @@ pub fn owned<D: Domain, V: Value<D> + 'static>(v: V) -> PlainValue<'static, D> {
Box::new(v)
}
pub fn arcvalue<D: Domain, V: Value<D> + 'static>(v: V) -> ArcValue<D> {
ArcValue(Arc::new(v))
}
pub fn iovalue<V: Value<IOValue> + 'static>(v: V) -> IOValue {
IOValue(Arc::new(v))
IOValue(arcvalue(v))
}
pub fn copy_via<D: Domain, E: Domain + 'static, F, Err>(
@ -189,7 +192,7 @@ impl<'a, Err: Into<io::Error>, D: Domain + FromStr<Err = Err> + 'static> FromStr
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::from_str(s, &mut DefaultDomainCodec)
crate::annotated_from_str(s, &mut DefaultDomainCodec)
}
}
@ -691,7 +694,7 @@ impl<'e, D: Domain, E: for<'a> Borrow<Key<'a, D>> + Ord + 'e> Value<D> for Set<E
pub struct Key<'a, D: Domain>(pub dyn Value<D> + 'a);
unsafe impl<'a, D: Domain> TransparentWrapper<dyn Value<D> + 'a> for Key<'a, D> {}
impl<'a, 'b: 'a, D: Domain> Borrow<Key<'a, D>> for Box<dyn Value<D> + 'b> {
impl<'a, 'b: 'a, D: Domain> Borrow<Key<'a, D>> for PlainValue<'b, D> {
fn borrow(&self) -> &Key<'a, D> {
Key::wrap_ref(&**self)
}
@ -864,40 +867,105 @@ impl<D: Domain, V: Value<D>> Ord for Annotations<D, V> {
}
#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct ArcValue<D: Domain + 'static = IOValue>(Arc<dyn Value<D>>);
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct IOValue(ArcValue);
impl<D: Domain> Debug for ArcValue<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
value(self).fmt(f)
}
}
impl Debug for IOValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
value(self).fmt(f)
}
}
impl FromStr for IOValue {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::iovalue_from_str(s)
}
}
impl PartialEq for IOValue {
impl<D: Domain> PartialEq for ArcValue<D> {
fn eq(&self, other: &Self) -> bool {
&self.0 == &other.0
}
}
impl<Err: Into<io::Error>, D: Domain + FromStr<Err = Err> + 'static> FromStr for ArcValue<D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(arcvalue(crate::annotated_from_str(s, &mut DefaultDomainCodec)?))
}
}
impl FromStr for IOValue {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::annotated_iovalue_from_str(s)
}
}
impl<D: Domain> From<PlainValue<'static, D>> for ArcValue<D> {
fn from(b: PlainValue<'static, D>) -> Self {
ArcValue(Arc::from(b))
}
}
impl From<PlainValue<'static, IOValue>> for IOValue {
fn from(b: PlainValue<'static, IOValue>) -> Self {
IOValue(Arc::from(b))
IOValue(b.into())
}
}
impl From<ArcValue<IOValue>> for IOValue {
fn from(b: ArcValue<IOValue>) -> Self {
IOValue(b)
}
}
impl<'a> Borrow<Key<'a, IOValue>> for IOValue {
fn borrow(&self) -> &Key<'a, IOValue> {
Key::wrap_ref(&*self.0.0)
}
}
impl<'a, D: Domain> Borrow<Key<'a, D>> for ArcValue<D> {
fn borrow(&self) -> &Key<'a, D> {
Key::wrap_ref(&*self.0)
}
}
impl<D: Domain> Value<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) -> PlainValue<'static, D> { Box::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<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) -> &dyn 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) -> &dyn Value<D> { self.0.index(i) }
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> { self.0.iter() }
fn is_set(&self) -> bool { self.0.is_set() }
fn has(&self, v: &dyn Value<D>) -> bool { self.0.has(v) }
fn is_dictionary(&self) -> bool { self.0.is_dictionary() }
fn get<'value>(&'value self, k: &dyn Value<D>) -> Option<&'value dyn Value<D>> { self.0.get(k) }
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn 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<&[IOValue]> { self.0.annotations() }
}
impl Value<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) -> PlainValue<'static, IOValue> { Box::new(self.clone()) }

View File

@ -11,13 +11,13 @@ use crate::BytesBinarySource;
use crate::Domain;
use crate::DomainDecode;
use crate::IOValue;
use crate::PlainValue;
use crate::Reader;
use crate::Value;
pub fn from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<Box<dyn Value<D>>> {
) -> io::Result<PlainValue<'static, D>> {
BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded)
}
@ -28,10 +28,51 @@ pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
pub fn annotated_from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<Box<dyn Value<D>>> {
) -> io::Result<PlainValue<'static, D>> {
BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded)
}
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(true)
}
#[cfg(test)]
mod formatting_tests {
use crate::IOValue;
use crate::test_domain::Dom;
use crate::ArcValue;
#[test] fn format_debug_and_parse() {
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<ArcValue<Dom>>().unwrap();
assert_eq!(format!("{:?}", &v), "[1, {a: #!\"One\", z: 2}, 3]");
}
#[test] fn format_pretty_debug_and_parse() {
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<ArcValue<Dom>>().unwrap();
assert_eq!(format!("{:#?}", &v), concat!(
"[\n",
" 1,\n",
" {\n",
" a: #!\"One\",\n",
" z: 2\n",
" },\n",
" 3\n",
"]"));
}
#[test] fn iovalue_parse() {
let v = "[1 @{a:b c:d} @\"foo\" #![2 3] 4]".parse::<IOValue>().unwrap();
assert_eq!(format!("{:#?}", &v), concat!(
"[\n",
" 1,\n",
" @{\n",
" a: b,\n",
" c: d\n",
" } @\"foo\" #![\n",
" 2,\n",
" 3\n",
" ],\n",
" 4\n",
"]"));
}
}