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::Set;
|
||||||
pub use repr::Symbol;
|
pub use repr::Symbol;
|
||||||
pub use repr::Value;
|
pub use repr::Value;
|
||||||
|
pub use repr::copy_via;
|
||||||
|
pub use repr::iovalue;
|
||||||
pub use repr::owned;
|
pub use repr::owned;
|
||||||
pub use repr::value;
|
pub use repr::value;
|
||||||
pub use signed_integer::SignedInteger;
|
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 bytemuck::TransparentWrapper;
|
||||||
|
|
||||||
|
use std::any::Any;
|
||||||
use std::borrow::{Cow, Borrow};
|
use std::borrow::{Cow, Borrow};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt::Debug;
|
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};
|
use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64};
|
||||||
|
|
||||||
pub type PlainValue<'a, D = IOValue> = Box<dyn Value<D> + 'a>;
|
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.
|
/// Atomic values from the specification.
|
||||||
pub trait Value<D: Domain> {
|
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 embedded(&self) -> Cow<'_, D> { panic!("Not an embedded value") }
|
||||||
|
|
||||||
fn annotations(&self) -> Option<&[IOValue]> { None }
|
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> {
|
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))
|
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> {
|
impl<'a, D: Domain + 'static> From<&'a dyn Value<D>> for PlainValue<'static, D> {
|
||||||
fn from(v: &'a dyn Value<D>) -> Self {
|
fn from(v: &'a dyn Value<D>) -> Self {
|
||||||
v.value_clone()
|
v.value_clone()
|
||||||
|
@ -490,7 +528,13 @@ impl<D: Domain> Value<D> for String {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
#[repr(transparent)]
|
#[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> {
|
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()) }
|
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);
|
pub struct Symbol<T: AsRef<str> + Debug = String>(T);
|
||||||
|
|
||||||
impl<T: AsRef<str> + Debug> Symbol<T> {
|
impl<T: AsRef<str> + Debug> Symbol<T> {
|
||||||
pub fn new<R: Into<T>>(t: R) -> Self {
|
pub fn new(t: T) -> Self {
|
||||||
Symbol(t.into())
|
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);
|
pub struct Embedded<D: Domain>(D);
|
||||||
|
|
||||||
impl<D: Domain> Embedded<D> {
|
impl<D: Domain> Embedded<D> {
|
||||||
pub fn new<E: Into<D>>(d: E) -> Self {
|
pub fn new(d: D) -> Self {
|
||||||
Embedded(d.into())
|
Embedded(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn embedded_value(&self) -> &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)]
|
#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct IOValue(Arc<dyn Value<IOValue>>);
|
pub struct IOValue(ArcValue);
|
||||||
|
|
||||||
impl Debug for IOValue {
|
impl Debug for IOValue {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
|
Loading…
Reference in New Issue