Customizable treatment of Domain during encoding

This commit is contained in:
Tony Garnock-Jones 2019-10-23 22:58:36 +01:00
parent 27fb961653
commit b1ca95c835
3 changed files with 74 additions and 12 deletions

View File

@ -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>>(
&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<N: NestedValue<Self>>(&self) -> Result<N, std::io::Error> {
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<PlainValue<Dom>, 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<PlainValue<Dom>, 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<PlainValue<Dom>, Dom>);

View File

@ -10,8 +10,8 @@ pub type Result = std::result::Result<(), Error>;
pub type EncodePlaceholderMap<N, D> = Map<Value<N, D>, usize>;
pub struct Encoder<'a, 'b, W: Write, N: NestedValue<D>, D: Domain> {
write: &'a mut W,
placeholders: Option<&'b EncodePlaceholderMap<N, D>>,
pub write: &'a mut W,
pub placeholders: Option<&'b EncodePlaceholderMap<N, D>>,
}
impl<'a, 'b, W: Write, N: NestedValue<D>, D: Domain> Encoder<'a, 'b, W, N, D> {
@ -117,10 +117,7 @@ impl<'a, 'b, W: Write, N: NestedValue<D>, 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),
}
}
}

View File

@ -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>>(
&self, enc: &mut super::encoder::Encoder<'a, 'b, W, N, Self>) ->
super::encoder::Result
{
enc.write(&self.as_preserves()?)
}
fn as_preserves<N: NestedValue<Self>>(&self) -> Result<N, std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::InvalidData,
format!("Cannot Preserves-encode domain-specific value {:?}",
self)))
}
}
pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
type BoxType: Sized + Debug + Clone + Eq + Hash + Ord;