From a548485b2ecf80c6adc3005f969e588939b6bf66 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 17 Sep 2019 00:58:32 +0100 Subject: [PATCH] Rust serde glue (wip) --- implementations/rust/Cargo.toml | 2 +- implementations/rust/src/lib.rs | 78 ++++- implementations/rust/src/value/de.rs | 364 ++++++++++++++++++++++ implementations/rust/src/value/encoder.rs | 8 +- implementations/rust/src/value/error.rs | 31 ++ implementations/rust/src/value/mod.rs | 20 +- implementations/rust/src/value/ser.rs | 296 ++++++++++++++++++ implementations/rust/src/value/value.rs | 98 ++++++ 8 files changed, 881 insertions(+), 16 deletions(-) create mode 100644 implementations/rust/src/value/de.rs create mode 100644 implementations/rust/src/value/error.rs create mode 100644 implementations/rust/src/value/ser.rs diff --git a/implementations/rust/Cargo.toml b/implementations/rust/Cargo.toml index b355eb1..df8b5bd 100644 --- a/implementations/rust/Cargo.toml +++ b/implementations/rust/Cargo.toml @@ -7,5 +7,5 @@ edition = "2018" [dependencies] num = "0.2" num_enum = "0.4.1" -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11" diff --git a/implementations/rust/src/lib.rs b/implementations/rust/src/lib.rs index 4b33935..f2aadb7 100644 --- a/implementations/rust/src/lib.rs +++ b/implementations/rust/src/lib.rs @@ -4,7 +4,7 @@ pub mod value; mod ieee754_section_5_10_total_order_tests { use std::cmp::Ordering::{Less, Equal, Greater}; - use crate::value::value::Value; + use crate::value::Value; // fn v(val: T) -> Value where Value: std::convert::From { Value::from(val) } fn f(val: f32) -> Value { Value::from(val) } fn d(val: f64) -> Value { Value::from(val) } @@ -97,7 +97,7 @@ mod ieee754_section_5_10_total_order_tests { #[cfg(test)] mod value_tests { - use crate::value::value::Value; + use crate::value::Value; use num::bigint::BigInt; #[test] fn boolean_mut() { @@ -175,9 +175,8 @@ mod value_tests { #[cfg(test)] mod decoder_tests { - use crate::value::decoder::Decoder; - use crate::value::encoder::Encoder; - use crate::value::value::Value; + use crate::value::Decoder; + use crate::value::Value; #[test] fn read_123() { let mut d = Decoder::new(&b"abc"[..], None); @@ -189,7 +188,7 @@ mod decoder_tests { #[test] fn skip_annotations_noskip() { let mut d = Decoder::new(&b"\x0521"[..], None); - let v = d.next().ok().unwrap(); + let v = d.next().unwrap(); assert_eq!(v.annotations().len(), 1); assert_eq!(v.annotations()[0], Value::from(2).wrap()); assert_eq!(v.value(), &Value::from(1)); @@ -198,18 +197,75 @@ mod decoder_tests { #[test] fn skip_annotations_skip() { let mut d = Decoder::new(&b"\x0521"[..], None); d.set_read_annotations(false); - let v = d.next().ok().unwrap(); + let v = d.next().unwrap(); assert_eq!(v.annotations().len(), 0); assert_eq!(v.value(), &Value::from(1)); } +} - #[test] fn read_samples() { +#[cfg(test)] +mod samples_tests { + use crate::value::Decoder; + use crate::value::{Value, AValue}; + use crate::value::DecodePlaceholderMap; + use crate::value::to_value; + use crate::value::from_value; + use std::collections::BTreeMap; + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + struct ExpectedPlaceholderMapping(DecodePlaceholderMap); + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + struct TestCases { + decode_placeholders: ExpectedPlaceholderMapping, + tests: BTreeMap + } + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + enum TestCase { + Test(#[serde(with = "serde_bytes")] Vec, AValue), + NondeterministicTest(#[serde(with = "serde_bytes")] Vec, AValue), + StreamingTest(#[serde(with = "serde_bytes")] Vec, AValue), + ParseError(String), + ParseShort(String), + DecodeError(#[serde(with = "serde_bytes")] Vec), + DecodeShort(#[serde(with = "serde_bytes")] Vec), + } + + #[test] fn run() { let mut d = Decoder::new(std::fs::File::open("../../tests/samples.bin").unwrap(), None); - let v = d.next().ok().unwrap(); - println!("{:#?}", v); + let v = d.next().unwrap(); + // println!("{:#?}", v); + + let tests: TestCases = from_value(&v).unwrap(); + println!("{:#?}", tests); + // let mut buf = Vec::new(); // let mut e = Encoder::new(&mut buf, None); - // e.write(&v).ok().unwrap(); + // e.write(&v).unwrap(); // println!("{:?}", Value::from(buf)) } + + #[test] fn simple_to_value() { + #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + struct SimpleValue<'a>(String, + &'a str, + #[serde(with = "serde_bytes")] &'a [u8], + #[serde(with = "serde_bytes")] Vec, + i16, + AValue); + let v = SimpleValue("hello".to_string(), + "world", + &b"slice"[..], + b"vec".to_vec(), + 12345, + Value::from("hi").wrap()); + println!("{:#?}", v); + let w = to_value(&v).unwrap(); + println!("{:#?}", w); + let x = from_value(&w).unwrap(); + println!("{:#?}", &x); + assert_eq!(v, x); + } } diff --git a/implementations/rust/src/value/de.rs b/implementations/rust/src/value/de.rs new file mode 100644 index 0000000..91dd2a7 --- /dev/null +++ b/implementations/rust/src/value/de.rs @@ -0,0 +1,364 @@ +use crate::value::{Value, AValue, Dictionary}; +use crate::value::value::{Float, Double}; +use crate::value::error::{Error, Result}; +use num::traits::cast::ToPrimitive; +use serde::Deserialize; +use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed}; +use std::convert::TryFrom; +use std::iter::Iterator; + +pub struct Deserializer<'de> { + input: &'de AValue, +} + +pub fn from_value<'a, T>(v: &'a AValue) -> Result where T: Deserialize<'a> { + let mut de = Deserializer::from_value(v); + let t = T::deserialize(&mut de)?; + Ok(t) +} + +impl<'de> Deserializer<'de> { + pub fn from_value(v: &'de AValue) -> Self { + Deserializer{ input: v } + } +} + +impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> + { + let v = self.input.value(); + match v { + Value::Boolean(b) => visitor.visit_bool(*b), + Value::Float(Float(f)) => visitor.visit_f32(*f), + Value::Double(Double(d)) => visitor.visit_f64(*d), + Value::SignedInteger(ref i) => + match i.to_i64() { + None => match i.to_u64() { + None => Err(Error::NumberTooLarge(i.clone())), + Some(n) => visitor.visit_u64(n), + } + Some(n) => visitor.visit_i64(n), + } + Value::String(ref s) => visitor.visit_str(&s), + Value::ByteString(_) => self.deserialize_bytes(visitor), + Value::Record(_) => + if v.is_simple_record("tuple", Some(0)) { + self.deserialize_unit(visitor) + } else if v.is_simple_record("UnicodeScalar", Some(1)) { + self.deserialize_char(visitor) + } else + if v.is_simple_record("None", Some(0)) || + v.is_simple_record("Some", Some(1)) + { + self.deserialize_option(visitor) + } else if v.is_simple_record("tuple", None) { + visitor.visit_seq(VecSeq::new(self, v.as_simple_record("tuple", None).unwrap())) + } else { + Err(Error::Syntax) + } + Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v)), + Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)), + _ => Err(Error::Syntax), + } + } + + fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_bool(self.input.value().as_boolean().ok_or(Error::Syntax)?) + } + + fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_i8(i.to_i8().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_i16(i.to_i16().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_i32(i.to_i32().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_i64(i.to_i64().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_u8(i.to_u8().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_u16(i.to_u16().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_u32(i.to_u32().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de> + { + let i = self.input.value().as_signedinteger().ok_or(Error::Syntax)?; + visitor.visit_u64(i.to_u64().ok_or(Error::NumberTooLarge(i.clone()))?) + } + + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_f32(self.input.value().as_float().ok_or(Error::Syntax)?) + } + + fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_f64(self.input.value().as_double().ok_or(Error::Syntax)?) + } + + fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de> + { + let fs = + self.input.value().as_simple_record("UnicodeScalar", Some(1)).ok_or(Error::Syntax)?; + if fs.len() != 1 { return Err(Error::Syntax) } + let c = fs[0].value().as_u32().ok_or(Error::Syntax)?; + visitor.visit_char(char::try_from(c).or(Err(Error::InvalidUnicodeScalar(c)))?) + } + + fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_borrowed_str(&self.input.value().as_string().ok_or(Error::Syntax)?) + } + + fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de> + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_borrowed_bytes(&self.input.value().as_bytestring().ok_or(Error::Syntax)?) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_byte_buf(self.input.value().as_bytestring().ok_or(Error::Syntax)?.clone()) + } + + fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> + { + match self.input.value().as_simple_record("None", Some(0)) { + Some(_fs) => visitor.visit_none(), + None => match self.input.value().as_simple_record("Some", Some(1)) { + Some(fs) => { + self.input = &fs[0]; + visitor.visit_some(self) + } + None => Err(Error::Syntax), + } + } + } + + fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de> + { + if self.input.value().is_simple_record("tuple", Some(0)) { + visitor.visit_unit() + } else { + Err(Error::Syntax) + } + } + + fn deserialize_unit_struct(self, name: &'static str, visitor: V) + -> Result where V: Visitor<'de> + { + if self.input.value().is_simple_record(name, Some(0)) { + visitor.visit_unit() + } else { + Err(Error::Syntax) + } + } + + fn deserialize_newtype_struct(self, name: &'static str, visitor: V) + -> Result where V: Visitor<'de> + { + if name == crate::value::value::MAGIC { + let mut buf: Vec = Vec::new(); + crate::value::Encoder::new(&mut buf, None).write(self.input) + .or_else(|_e| Err(Error::Message("Internal error".to_string())))?; + visitor.visit_byte_buf(buf) + } else { + let fs = self.input.value().as_simple_record(name, Some(1)).ok_or(Error::Syntax)?; + self.input = &fs[0]; + visitor.visit_newtype_struct(self) + } + } + + fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de> { + let vs = self.input.value().as_sequence().ok_or(Error::Syntax)?; + visitor.visit_seq(VecSeq::new(self, vs)) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de> + { + let fs = self.input.value().as_simple_record("tuple", Some(len)).ok_or(Error::Syntax)?; + visitor.visit_seq(VecSeq::new(self, fs)) + } + + fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) + -> Result where V: Visitor<'de> + { + let fs = self.input.value().as_simple_record(name, Some(len)).ok_or(Error::Syntax)?; + visitor.visit_seq(VecSeq::new(self, fs)) + } + + fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de> { + let d = self.input.value().as_dictionary().ok_or(Error::Syntax)?; + visitor.visit_map(DictMap::new(self, d)) + } + + fn deserialize_struct(self, + name: &'static str, + fields: &'static [&'static str], + visitor: V) + -> Result where V: Visitor<'de> + { + let fs = + self.input.value().as_simple_record(name, Some(fields.len())).ok_or(Error::Syntax)?; + visitor.visit_seq(VecSeq::new(self, fs)) + } + + fn deserialize_enum(self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V) + -> Result where V: Visitor<'de> + { + visitor.visit_enum(self) + } + + fn deserialize_identifier(self, visitor: V) -> Result where V: Visitor<'de> + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result where V: Visitor<'de> + { + visitor.visit_none() + } +} + +pub struct VecSeq<'a, 'de: 'a> { + index: usize, + vec: &'de Vec, + de: &'a mut Deserializer<'de>, +} + +impl<'de, 'a> VecSeq<'a, 'de> { + fn new(de: &'a mut Deserializer<'de>, vec: &'de Vec) -> Self { + VecSeq{ index: 0, vec, de } + } +} + +impl<'de, 'a> SeqAccess<'de> for VecSeq<'a, 'de> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) + -> Result> where T: DeserializeSeed<'de> + { + if self.index == self.vec.len() { + return Ok(None) + } + + self.de.input = &self.vec[self.index]; + self.index = self.index + 1; + let value = seed.deserialize(&mut *self.de)?; + Ok(Some(value)) + } +} + +pub struct DictMap<'a, 'de: 'a> { + pending: Option<&'de AValue>, + iter: Box + 'a>, + de: &'a mut Deserializer<'de>, +} + +impl<'de, 'a> DictMap<'a, 'de> { + fn new(de: &'a mut Deserializer<'de>, d: &'de Dictionary) -> Self { + DictMap{ pending: None, iter: Box::new(d.into_iter()), de } + } +} + +impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) + -> Result> where K: DeserializeSeed<'de> + { + match self.iter.next() { + None => Ok(None), + Some((k, v)) => { + self.pending = Some(v); + self.de.input = k; + Ok(Some(seed.deserialize(&mut *self.de)?)) + } + } + } + + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de> { + let v = self.pending.unwrap(); + self.pending = None; + self.de.input = v; + Ok(seed.deserialize(&mut *self.de)?) + } +} + +impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) + -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> + { + let v = self.input; + let (lp, _) = v.value().as_record().ok_or(Error::Syntax)?; + self.input = lp; + let variant = seed.deserialize(&mut *self)?; + self.input = v; + Ok((variant, self)) + } +} + +impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de> { + let (_, fs) = self.input.value().as_record().unwrap(); + self.input = &fs[0]; + seed.deserialize(&mut *self) + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result where V: Visitor<'de> { + visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record().unwrap().1)) + } + + fn struct_variant(self, _fields: &'static [&'static str], visitor: V) + -> Result where V: Visitor<'de> + { + visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record().unwrap().1)) + } +} diff --git a/implementations/rust/src/value/encoder.rs b/implementations/rust/src/value/encoder.rs index 87ba959..e41504b 100644 --- a/implementations/rust/src/value/encoder.rs +++ b/implementations/rust/src/value/encoder.rs @@ -78,9 +78,13 @@ impl<'a, W: Write> Encoder<'a, W> { self.write_header(Op::Misc(0), 5)?; self.write(ann)?; } - match self.placeholders.get(&v.value()) { + self.write_value(v.value()) + } + + pub fn write_value(&mut self, v: &Value) -> Result { + match self.placeholders.get(v) { Some(&n) => self.write_header(Op::Misc(1), n), - None => match v.value() { + None => match v { Value::Boolean(false) => self.write_op(Op::Misc(0), 0), Value::Boolean(true) => self.write_op(Op::Misc(0), 1), Value::Float(Float(f)) => { diff --git a/implementations/rust/src/value/error.rs b/implementations/rust/src/value/error.rs new file mode 100644 index 0000000..df52c59 --- /dev/null +++ b/implementations/rust/src/value/error.rs @@ -0,0 +1,31 @@ +use num::bigint::BigInt; + +#[derive(Debug)] +pub enum Error { + Message(String), + Syntax, + InvalidUnicodeScalar(u32), + NumberTooLarge(BigInt), +} + +pub type Result = std::result::Result; + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + Self::Message(msg.to_string()) + } +} + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self { + Self::Message(msg.to_string()) + } +} + +impl std::error::Error for Error {} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} diff --git a/implementations/rust/src/value/mod.rs b/implementations/rust/src/value/mod.rs index a4eac26..ad8eb7b 100644 --- a/implementations/rust/src/value/mod.rs +++ b/implementations/rust/src/value/mod.rs @@ -1,4 +1,20 @@ -pub mod value; +pub mod constants; +pub mod de; pub mod decoder; pub mod encoder; -pub mod constants; +pub mod error; +pub mod ser; +pub mod value; + +pub use de::Deserializer; +pub use de::from_value; +pub use decoder::DecodePlaceholderMap; +pub use decoder::Decoder; +pub use encoder::EncodePlaceholderMap; +pub use encoder::Encoder; +pub use ser::Serializer; +pub use ser::to_value; +pub use value::AValue; +pub use value::Dictionary; +pub use value::Set; +pub use value::Value; diff --git a/implementations/rust/src/value/ser.rs b/implementations/rust/src/value/ser.rs new file mode 100644 index 0000000..d3a921b --- /dev/null +++ b/implementations/rust/src/value/ser.rs @@ -0,0 +1,296 @@ +use crate::value::{Value, AValue, Dictionary}; +use serde::Serialize; +use crate::value::error::{Error, Result}; + +pub struct Serializer; + +pub struct SerializeDictionary { + next_key: Option, + items: Dictionary, +} + +pub struct SerializeRecord { + name: &'static str, + vec: Vec, +} + +pub struct SerializeSequence { + vec: Vec, +} + +impl serde::Serializer for Serializer { + type Ok = AValue; + type Error = Error; + type SerializeSeq = SerializeSequence; + type SerializeTuple = SerializeRecord; + type SerializeTupleStruct = SerializeRecord; + type SerializeTupleVariant = SerializeRecord; + type SerializeMap = SerializeDictionary; + type SerializeStruct = SerializeRecord; + type SerializeStructVariant = SerializeRecord; + + fn serialize_bool(self, v: bool) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_i8(self, v: i8) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_i16(self, v: i16) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_i32(self, v: i32) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_i64(self, v: i64) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_u8(self, v: u8) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_u16(self, v: u16) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_u32(self, v: u32) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_f32(self, v: f32) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_f64(self, v: f64) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_char(self, v: char) -> Result { + Ok(Value::simple_record("UnicodeScalar", vec![Value::from(v as u32).wrap()]).wrap()) + } + + fn serialize_str(self, v: &str) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + Ok(Value::from(v).wrap()) + } + + fn serialize_none(self) -> Result { + Ok(Value::simple_record("None", vec![]).wrap()) + } + + fn serialize_some(self, v: &T) -> Result where T: Serialize { + Ok(Value::simple_record("Some", vec![to_value(v)?]).wrap()) + } + + fn serialize_unit(self) -> Result { + Ok(Value::simple_record("tuple", vec![]).wrap()) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + Ok(Value::simple_record(name, vec![]).wrap()) + } + + fn serialize_unit_variant(self, + _name: &'static str, + _variant: u32, + variant_name: &'static str) -> + Result + { + Ok(Value::simple_record(variant_name, vec![]).wrap()) + } + + fn serialize_newtype_struct(self, name: &'static str, value: &T) -> + Result where T: Serialize + { + if name == crate::value::value::MAGIC { + let v = to_value(value)?; + let buf: &[u8] = v.value().as_bytestring().ok_or(Error::Syntax)?; + crate::value::Decoder::new(buf, None).next().or(Err(Error::Syntax)) + } else { + // TODO: This is apparently discouraged, and we should apparently just serialize `value`? + Ok(Value::simple_record(name, vec![to_value(value)?]).wrap()) + } + } + + fn serialize_newtype_variant(self, + _name: &'static str, + _variant: u32, + variant_name: &'static str, + value: &T) -> + Result where T: Serialize + { + Ok(Value::simple_record(variant_name, vec![to_value(value)?]).wrap()) + } + + fn serialize_seq(self, count: Option) -> Result { + let vec = match count { Some(n) => Vec::with_capacity(n), None => Vec::new() }; + Ok(SerializeSequence{ vec }) + } + + fn serialize_tuple(self, count: usize) -> Result { + Ok(SerializeRecord{ name: "tuple", vec: Vec::with_capacity(count) }) + } + + fn serialize_tuple_struct(self, name: &'static str, count: usize) -> + Result + { + Ok(SerializeRecord{ name, vec: Vec::with_capacity(count) }) + } + + fn serialize_tuple_variant(self, + _name: &'static str, + _variant: u32, + variant_name: &'static str, + count: usize) -> + Result + { + Ok(SerializeRecord{ name: variant_name, vec: Vec::with_capacity(count) }) + } + + fn serialize_map(self, _count: Option) -> Result { + Ok(SerializeDictionary{ next_key: None, items: Dictionary::new() }) + } + + fn serialize_struct(self, name: &'static str, count: usize) -> Result { + Ok(SerializeRecord{ name, vec: Vec::with_capacity(count) }) + } + + fn serialize_struct_variant(self, + _name: &'static str, + _variant: u32, + variant_name: &'static str, + count: usize) -> + Result + { + Ok(SerializeRecord{ name: variant_name, vec: Vec::with_capacity(count) }) + } +} + +impl serde::ser::SerializeMap for SerializeDictionary { + type Ok = AValue; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<()> where T: Serialize { + self.next_key = Some(to_value(key)?); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<()> where T: Serialize { + let key = self.next_key.take().unwrap(); + self.items.insert(key, to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::from(self.items).wrap()) + } +} + +impl SerializeRecord { + fn push(&mut self, value: AValue) -> Result<()> { + self.vec.push(value); + Ok(()) + } + + fn finish(self) -> Result { + Ok(Value::simple_record(self.name, self.vec).wrap()) + } +} + +impl serde::ser::SerializeStruct for SerializeRecord { + type Ok = AValue; + type Error = Error; + + fn serialize_field(&mut self, _name: &'static str, value: &T) -> Result<()> + where T: Serialize + { + self.push(to_value(value)?) + } + + fn end(self) -> Result { + self.finish() + } +} + +impl serde::ser::SerializeStructVariant for SerializeRecord { + type Ok = AValue; + type Error = Error; + + fn serialize_field(&mut self, _name: &'static str, value: &T) -> Result<()> + where T: Serialize + { + self.push(to_value(value)?) + } + + fn end(self) -> Result { + self.finish() + } +} + +impl serde::ser::SerializeTuple for SerializeRecord { + type Ok = AValue; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> where T: Serialize { + self.push(to_value(value)?) + } + + fn end(self) -> Result { + self.finish() + } +} + +impl serde::ser::SerializeTupleStruct for SerializeRecord { + type Ok = AValue; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> where T: Serialize { + self.push(to_value(value)?) + } + + fn end(self) -> Result { + self.finish() + } +} + +impl serde::ser::SerializeTupleVariant for SerializeRecord { + type Ok = AValue; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> where T: Serialize { + self.push(to_value(value)?) + } + + fn end(self) -> Result { + self.finish() + } +} + +impl serde::ser::SerializeSeq for SerializeSequence { + type Ok = AValue; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> where T: Serialize { + self.vec.push(to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::from(self.vec).wrap()) + } +} + +pub fn to_value(value: T) -> Result where T: Serialize { + value.serialize(Serializer) +} diff --git a/implementations/rust/src/value/value.rs b/implementations/rust/src/value/value.rs index 08b7ca7..249ae6f 100644 --- a/implementations/rust/src/value/value.rs +++ b/implementations/rust/src/value/value.rs @@ -8,6 +8,7 @@ use std::collections::BTreeSet; use std::collections::BTreeMap; use std::ops::Index; use std::ops::IndexMut; +use num::traits::cast::ToPrimitive; /// The `Value`s from the specification. #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -179,6 +180,8 @@ impl From<&[u8]> for Value { fn from(v: &[u8]) -> Self { Value::ByteString(Vec:: impl From> for Value { fn from(v: Vec) -> Self { Value::ByteString(v) } } impl From> for Value { fn from(v: Vec) -> Self { Value::Sequence(v) } } +impl From for Value { fn from(v: Set) -> Self { Value::Set(v) } } +impl From for Value { fn from(v: Dictionary) -> Self { Value::Dictionary(v) } } impl std::fmt::Debug for Value { // Not *quite* a formatter for the Preserves text syntax, since it @@ -341,6 +344,15 @@ impl Value { } } + pub fn as_u8(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_u8()) } + pub fn as_i8(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_i8()) } + pub fn as_u16(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_u16()) } + pub fn as_i16(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_i16()) } + pub fn as_u32(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_u32()) } + pub fn as_i32(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_i32()) } + pub fn as_u64(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_u64()) } + pub fn as_i64(&self) -> Option { self.as_signedinteger().and_then(|i| i.to_i64()) } + pub fn is_string(&self) -> bool { self.as_string().is_some() } @@ -429,6 +441,28 @@ impl Value { } } + pub fn simple_record(label: &str, fields: Vec) -> Value { + Value::record(&Rc::new(Value::symbol(label).wrap()), fields) + } + + pub fn is_simple_record(&self, label: &str, arity: Option) -> bool { + self.as_simple_record(label, arity).is_some() + } + + pub fn as_simple_record(&self, label: &str, arity: Option) -> Option<&Vec> { + self.as_record().and_then(|(lp,fs)| { + match *lp.value() { + Value::Symbol(ref s) if s == label => + match arity { + Some(expected) if fs.len() == expected => Some(fs), + Some(_other) => None, + None => Some(fs) + } + _ => None + } + }) + } + pub fn is_sequence(&self) -> bool { self.as_sequence().is_some() } @@ -511,3 +545,67 @@ impl Index<&AValue> for Value { &self.as_dictionary().unwrap()[i] } } + +//--------------------------------------------------------------------------- +// This part is a terrible hack + +pub static MAGIC: &str = "$____Preserves_Value"; + +#[derive(serde::Serialize)] +#[serde(rename = "$____Preserves_Value")] +struct ValueWrapper(#[serde(with = "serde_bytes")] Vec); + +struct ValueWrapperVisitor; + +impl<'de> serde::de::Visitor<'de> for ValueWrapperVisitor { + type Value = ValueWrapper; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "an encoded value wrapper") + } + + fn visit_bytes(self, v: &[u8]) -> Result where E: serde::de::Error { + Ok(ValueWrapper(Vec::from(v))) + } +} + +impl<'de> serde::Deserialize<'de> for ValueWrapper { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + deserializer.deserialize_newtype_struct(MAGIC, ValueWrapperVisitor) + } +} + +impl serde::Serialize for Value { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + let mut buf: Vec = Vec::new(); + crate::value::Encoder::new(&mut buf, None).write_value(self) + .or(Err(serde::ser::Error::custom("Internal error")))?; + ValueWrapper(buf).serialize(serializer) + } +} + +impl serde::Serialize for AValue { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + let mut buf: Vec = Vec::new(); + crate::value::Encoder::new(&mut buf, None).write(self) + .or(Err(serde::ser::Error::custom("Internal error")))?; + ValueWrapper(buf).serialize(serializer) + } +} + +impl<'de> serde::Deserialize<'de> for Value { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + let ValueWrapper(buf) = ValueWrapper::deserialize(deserializer)?; + let v = crate::value::Decoder::new(&buf[..], None).next() + .or(Err(serde::de::Error::custom("Internal error")))?; + Ok(v.value().clone()) + } +} + +impl<'de> serde::Deserialize<'de> for AValue { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + let ValueWrapper(buf) = ValueWrapper::deserialize(deserializer)?; + crate::value::Decoder::new(&buf[..], None).next() + .or(Err(serde::de::Error::custom("Internal error"))) + } +}