diff --git a/implementations/rust/src/lib.rs b/implementations/rust/src/lib.rs index acc9c43..210248c 100644 --- a/implementations/rust/src/lib.rs +++ b/implementations/rust/src/lib.rs @@ -2,12 +2,64 @@ pub mod value; pub mod symbol; #[cfg(test)] -type Dom = (); +mod dom { + use super::value::{Value, PlainValue, NestedValue, Domain, Encoder, Codec}; + + #[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)] + pub enum Dom { + One, + Two, + } + + impl Domain for Dom { + fn encode<'a, 'b, W: std::io::Write, N: NestedValue>( + &self, enc: &mut Encoder<'a, 'b, W, N, Self>) -> + super::value::encoder::Result + { + match self { + Dom::One => enc.write_all(&[255, 255, 255, 255]), + Dom::Two => enc.write(&self.as_preserves()?) + } + } + + fn as_preserves>(&self) -> Result { + Ok(Value::symbol(&format!("Dom::{:?}", self)).wrap()) + } + } + + #[test] fn test_one() { + let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), + Value::Domain(Dom::One).wrap(), + Value::from(2).wrap()]) + .wrap(); + assert_eq!(Codec::without_placeholders().encode_bytes(&v).unwrap(), + [147, 49, 255, 255, 255, 255, 50]); + } + + #[test] fn test_two() { + let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), + Value::Domain(Dom::Two).wrap(), + Value::from(2).wrap()]) + .wrap(); + assert_eq!(Codec::without_placeholders().encode_bytes(&v).unwrap(), + [147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]); + } + + #[test] fn test_unit() { + let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), + Value::Domain(()).wrap(), + Value::from(2).wrap()]) + .wrap(); + let e = Codec::without_placeholders().encode_bytes(&v).err().unwrap(); + assert_eq!(e.kind(), std::io::ErrorKind::InvalidData); + assert_eq!(e.to_string(), "Cannot Preserves-encode domain-specific value ()"); + } +} #[cfg(test)] mod ieee754_section_5_10_total_order_tests { use std::cmp::Ordering::{Less, Equal, Greater}; - use super::Dom; + use super::dom::Dom; use crate::value::{Value, PlainValue}; fn f(val: f32) -> Value, Dom> { Value::from(val) } @@ -103,7 +155,7 @@ mod ieee754_section_5_10_total_order_tests { mod value_tests { use crate::value::{Value, PlainValue}; use num::bigint::BigInt; - use super::Dom; + use super::dom::Dom; type VV = Value, Dom>; @@ -184,7 +236,7 @@ mod value_tests { mod decoder_tests { use crate::value::Decoder; use crate::value::{Value, PlainValue, NestedValue}; - use super::Dom; + use super::dom::Dom; #[test] fn read_123() { let mut buf = &b"abc"[..]; @@ -239,7 +291,7 @@ mod samples_tests { use crate::value::DecodePlaceholderMap; use crate::value::to_value; use crate::value::from_value; - use super::Dom; + use super::dom::Dom; #[derive(Debug, serde::Serialize, serde::Deserialize)] struct ExpectedPlaceholderMapping(DecodePlaceholderMap, Dom>); diff --git a/implementations/rust/src/value/encoder.rs b/implementations/rust/src/value/encoder.rs index bb12aae..55b102e 100644 --- a/implementations/rust/src/value/encoder.rs +++ b/implementations/rust/src/value/encoder.rs @@ -10,8 +10,8 @@ pub type Result = std::result::Result<(), Error>; pub type EncodePlaceholderMap = Map, usize>; pub struct Encoder<'a, 'b, W: Write, N: NestedValue, D: Domain> { - write: &'a mut W, - placeholders: Option<&'b EncodePlaceholderMap>, + pub write: &'a mut W, + pub placeholders: Option<&'b EncodePlaceholderMap>, } impl<'a, 'b, W: Write, N: NestedValue, D: Domain> Encoder<'a, 'b, W, N, D> { @@ -117,10 +117,7 @@ impl<'a, 'b, W: Write, N: NestedValue, D: Domain> Encoder<'a, 'b, W, N, D> { for (k, v) in vs { self.write(k)?; self.write(v)?; } Ok(()) } - Value::Domain(ref d) => - Err(Error::new(std::io::ErrorKind::InvalidData, - format!("Cannot Preserves-encode domain-specific value {:?}", - d))), + Value::Domain(ref d) => d.encode(self), } } } diff --git a/implementations/rust/src/value/value.rs b/implementations/rust/src/value/value.rs index d100c4c..5b6731e 100644 --- a/implementations/rust/src/value/value.rs +++ b/implementations/rust/src/value/value.rs @@ -11,7 +11,20 @@ use num::traits::cast::ToPrimitive; pub use std::collections::BTreeSet as Set; pub use std::collections::BTreeMap as Map; -pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord {} +pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord { + fn encode<'a, 'b, W: std::io::Write, N: NestedValue>( + &self, enc: &mut super::encoder::Encoder<'a, 'b, W, N, Self>) -> + super::encoder::Result + { + enc.write(&self.as_preserves()?) + } + + fn as_preserves>(&self) -> Result { + Err(std::io::Error::new(std::io::ErrorKind::InvalidData, + format!("Cannot Preserves-encode domain-specific value {:?}", + self))) + } +} pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord { type BoxType: Sized + Debug + Clone + Eq + Hash + Ord;