copy_via, more library
This commit is contained in:
parent
228f34c699
commit
274c8b617d
|
@ -32,6 +32,8 @@ pub use repr::Record;
|
|||
pub use repr::Set;
|
||||
pub use repr::Symbol;
|
||||
pub use repr::Value;
|
||||
pub use repr::copy_via;
|
||||
pub use repr::iovalue;
|
||||
pub use repr::owned;
|
||||
pub use repr::value;
|
||||
pub use signed_integer::SignedInteger;
|
||||
|
@ -92,3 +94,84 @@ mod demo {
|
|||
// }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_domain {
|
||||
use std::io;
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)]
|
||||
pub enum Dom {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
impl Domain for Dom {
|
||||
type Decode = DebugDomainCodec;
|
||||
type Encode = DebugDomainCodec;
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Dom {
|
||||
type Err = io::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"One" => Ok(Dom::One),
|
||||
"Two" => Ok(Dom::Two),
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, "cannot parse preserves test domain")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DomCodec;
|
||||
|
||||
impl DomainDecode<Dom> for DomCodec {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
r: &mut R,
|
||||
_read_annotations: bool,
|
||||
) -> io::Result<Dom> {
|
||||
let v = r.next_iovalue(false)?;
|
||||
if v.as_bytestring().is_some() {
|
||||
Ok(Dom::One)
|
||||
} else {
|
||||
Ok(Dom::Two)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DomainEncode<Dom> for DomCodec {
|
||||
fn encode_embedded(
|
||||
&mut self,
|
||||
w: &mut dyn Writer,
|
||||
d: &Dom,
|
||||
) -> io::Result<()> {
|
||||
match d {
|
||||
Dom::One => Bytes::new(vec![255, 255, 255, 255]).write(w, self),
|
||||
Dom::Two => Symbol::new(&format!("Dom::{:?}", d)).write(w, self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dom_as_preserves(v: &Dom) -> io::Result<PlainValue<'static, IOValue>> {
|
||||
Ok(match v {
|
||||
Dom::One => owned(Bytes::new(vec![255, 255, 255, 255])),
|
||||
Dom::Two => owned(Symbol::new(format!("Dom::{:?}", v))),
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn test_one() {
|
||||
let v = owned(vec![owned(1),
|
||||
owned(Embedded::new(Dom::One)),
|
||||
owned(2)]);
|
||||
assert_eq!(PackedWriter::encode_iovalue(&iovalue(copy_via(&v, &mut dom_as_preserves).unwrap())).unwrap(),
|
||||
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
|
||||
}
|
||||
|
||||
#[test] fn test_two() {
|
||||
let v = owned(vec![owned(1),
|
||||
owned(Embedded::new(Dom::Two)),
|
||||
owned(2)]);
|
||||
assert_eq!(PackedWriter::encode_iovalue(&iovalue(copy_via(&v, &mut dom_as_preserves).unwrap())).unwrap(),
|
||||
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use bytemuck::TransparentWrapper;
|
||||
|
||||
use std::any::Any;
|
||||
use std::borrow::{Cow, Borrow};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::Debug;
|
||||
|
@ -25,6 +26,7 @@ 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> {
|
||||
|
@ -65,6 +67,8 @@ pub trait Value<D: Domain> {
|
|||
fn embedded(&self) -> Cow<'_, D> { panic!("Not an embedded value") }
|
||||
|
||||
fn annotations(&self) -> Option<&[IOValue]> { None }
|
||||
|
||||
fn specialized(&self) -> Option<&dyn Any> { None }
|
||||
}
|
||||
|
||||
pub fn value<D: Domain, V: Value<D>>(v: &V) -> &dyn Value<D> {
|
||||
|
@ -79,6 +83,40 @@ pub fn iovalue<V: Value<IOValue> + 'static>(v: V) -> IOValue {
|
|||
IOValue(Arc::new(v))
|
||||
}
|
||||
|
||||
pub fn copy_via<D: Domain, E: Domain + 'static, F, Err>(
|
||||
v: &dyn Value<D>,
|
||||
f: &mut F,
|
||||
) -> Result<PlainValue<'static, E>, Err>
|
||||
where
|
||||
F: FnMut(&D) -> Result<PlainValue<'static, E>, Err>
|
||||
{
|
||||
match v.value_class() {
|
||||
ValueClass::Atomic(a) => Ok(match a {
|
||||
AtomClass::Boolean => owned(v.as_boolean().unwrap()),
|
||||
AtomClass::Float => owned(v.as_float().unwrap()),
|
||||
AtomClass::Double => owned(v.as_double().unwrap()),
|
||||
AtomClass::SignedInteger => owned(v.as_signed_integer().unwrap()),
|
||||
AtomClass::String => owned(v.as_string().unwrap().into_owned()),
|
||||
AtomClass::ByteString => owned(Bytes(v.as_bytestring().unwrap().into_owned())),
|
||||
AtomClass::Symbol => owned(Symbol(v.as_symbol().unwrap().into_owned())),
|
||||
}),
|
||||
ValueClass::Compound(c) => Ok(match c {
|
||||
CompoundClass::Sequence =>
|
||||
owned(v.iter().map(|w| copy_via(w, f)).collect::<Result<Vec<_>, _>>()?),
|
||||
CompoundClass::Set =>
|
||||
owned(v.iter().map(|w| copy_via(w, f)).collect::<Result<Set<_>, _>>()?),
|
||||
CompoundClass::Record =>
|
||||
owned(Record::new(
|
||||
copy_via(v.label(), f)?,
|
||||
v.iter().map(|w| copy_via(w, f)).collect::<Result<Vec<_>, _>>()?)),
|
||||
CompoundClass::Dictionary =>
|
||||
owned(v.entries().map(|(k, w)| Ok((copy_via(k, f)?, copy_via(w, f)?)))
|
||||
.collect::<Result<Map<_, _>, _>>()?),
|
||||
}),
|
||||
ValueClass::Embedded => f(&v.embedded()),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: Domain + 'static> From<&'a dyn Value<D>> for PlainValue<'static, D> {
|
||||
fn from(v: &'a dyn Value<D>) -> Self {
|
||||
v.value_clone()
|
||||
|
@ -490,7 +528,13 @@ impl<D: Domain> Value<D> for String {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[repr(transparent)]
|
||||
pub struct Bytes<T: AsRef<[u8]>>(T);
|
||||
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, D: Domain> Value<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()) }
|
||||
|
@ -504,8 +548,8 @@ impl<T: AsRef<[u8]> + Debug, D: Domain> Value<D> for Bytes<T> {
|
|||
pub struct Symbol<T: AsRef<str> + Debug = String>(T);
|
||||
|
||||
impl<T: AsRef<str> + Debug> Symbol<T> {
|
||||
pub fn new<R: Into<T>>(t: R) -> Self {
|
||||
Symbol(t.into())
|
||||
pub fn new(t: T) -> Self {
|
||||
Symbol(t)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -702,8 +746,8 @@ impl<'k, D: Domain, V: Value<D>, K: for<'a> Borrow<Key<'a, D>> + Ord + 'k> Value
|
|||
pub struct Embedded<D: Domain>(D);
|
||||
|
||||
impl<D: Domain> Embedded<D> {
|
||||
pub fn new<E: Into<D>>(d: E) -> Self {
|
||||
Embedded(d.into())
|
||||
pub fn new(d: D) -> Self {
|
||||
Embedded(d)
|
||||
}
|
||||
|
||||
pub fn embedded_value(&self) -> &D {
|
||||
|
@ -820,7 +864,7 @@ impl<D: Domain, V: Value<D>> Ord for Annotations<D, V> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct IOValue(Arc<dyn Value<IOValue>>);
|
||||
pub struct IOValue(ArcValue);
|
||||
|
||||
impl Debug for IOValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
|
|
Loading…
Reference in New Issue