diff --git a/rmp-serde/CHANGELOG.md b/rmp-serde/CHANGELOG.md index f2592c38..1b17e0f5 100644 --- a/rmp-serde/CHANGELOG.md +++ b/rmp-serde/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][unreleased] +## 0.13.0 - 2017-04-24 ### Added - Zero-copy deserialization from `&[u8]`. diff --git a/rmp-serde/tests/decode_derive.rs b/rmp-serde/tests/decode_derive.rs index 80f798eb..436bd59b 100644 --- a/rmp-serde/tests/decode_derive.rs +++ b/rmp-serde/tests/decode_derive.rs @@ -311,3 +311,17 @@ fn pass_enum_with_one_arg() { assert_eq!(Enum::V1(vec![1, 2]), actual); assert_eq!(buf.len() as u64, de.get_ref().position()) } + +#[test] +fn pass_from_slice() { + let buf = [0x93, 0xa4, 0x4a, 0x6f, 0x68, 0x6e, 0xa5, 0x53, 0x6d, 0x69, 0x74, 0x68, 0x2a]; + + #[derive(Debug, PartialEq, Deserialize)] + struct Person<'a> { + name: &'a str, + surname: &'a str, + age: u8, + } + + assert_eq!(Person { name: "John", surname: "Smith", age: 42 }, rmps::from_slice(&buf[..]).unwrap()); +} diff --git a/rmp/CHANGELOG.md b/rmp/CHANGELOG.md index 8e7c4e5f..a141aa27 100644 --- a/rmp/CHANGELOG.md +++ b/rmp/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## 0.8.6 - 2017-04-23 ### Added - New `rmp::decode::read_str_from_slice` function for zero-copy reading strings from slices. diff --git a/rmp/Cargo.toml b/rmp/Cargo.toml index a77f32c2..66b11125 100644 --- a/rmp/Cargo.toml +++ b/rmp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmp" -version = "0.8.5" +version = "0.8.6" authors = ["Evgeny Safronov "] license = "MIT" description = "Pure Rust MessagePack serialization implementation" diff --git a/rmpv-tests/tests/de_ref.rs b/rmpv-tests/tests/de_ref.rs index ad52ab44..9e4f0a3b 100644 --- a/rmpv-tests/tests/de_ref.rs +++ b/rmpv-tests/tests/de_ref.rs @@ -248,3 +248,11 @@ fn pass_enum_from_value() { assert_eq!(Enum::Struct { name: "John", age: 42 }, deserialize_from(ValueRef::Array(vec![ValueRef::from(3), ValueRef::Array(vec![ValueRef::from("John"), ValueRef::from(42)])])).unwrap()); } + +#[test] +fn pass_from_slice() { + let buf = [0x93, 0xa4, 0x4a, 0x6f, 0x68, 0x6e, 0xa5, 0x53, 0x6d, 0x69, 0x74, 0x68, 0x2a]; + + assert_eq!(ValueRef::Array(vec![ValueRef::from("John"), ValueRef::from("Smith"), ValueRef::from(42)]), + rmps::from_slice(&buf[..]).unwrap()); +} diff --git a/rmpv/CHANGELOG.md b/rmpv/CHANGELOG.md index baa1a852..95bc7d27 100644 --- a/rmpv/CHANGELOG.md +++ b/rmpv/CHANGELOG.md @@ -3,9 +3,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## 0.4.0 - 2017-04-24 ### Added -- Implement `Deserialize` for `ValueRef`. -- Implement `Deserializer` for `ValueRef`. +- Implement `Deserialize` for `ValueRef<'de>`. +- Implement `Deserializer` for `ValueRef<'de>`. +- Implement `Deserializer` for `&'de ValueRef<'de>`. - Zero-copy deserialization from `ValueRef`. ### Changed diff --git a/rmpv/src/ext.rs b/rmpv/src/ext/de.rs similarity index 57% rename from rmpv/src/ext.rs rename to rmpv/src/ext/de.rs index 895da6f3..0f580728 100644 --- a/rmpv/src/ext.rs +++ b/rmpv/src/ext/de.rs @@ -1,57 +1,31 @@ -use std::error; use std::fmt::{self, Display, Formatter}; +use std::iter::ExactSizeIterator; +use std::slice::Iter; use std::vec::IntoIter; -use serde::{self, Serialize, Deserialize, Deserializer}; +use serde::{self, Deserialize, Deserializer}; use serde::de::{self, DeserializeSeed, IntoDeserializer, SeqAccess, Unexpected, Visitor}; -use serde::ser::{self, SerializeSeq, SerializeTuple, SerializeTupleStruct, SerializeMap, SerializeStruct}; -use serde_bytes::Bytes; use {Integer, IntPriv, Utf8String, Utf8StringRef, Value, ValueRef}; -impl Serialize for Value { - fn serialize(&self, s: S) -> Result - where S: ser::Serializer - { - match *self { - Value::Nil => s.serialize_unit(), - Value::Boolean(v) => s.serialize_bool(v), - Value::Integer(Integer { n }) => { - match n { - IntPriv::PosInt(n) => s.serialize_u64(n), - IntPriv::NegInt(n) => s.serialize_i64(n), - } - } - Value::F32(v) => s.serialize_f32(v), - Value::F64(v) => s.serialize_f64(v), - Value::String(ref v) => { - match v.s { - Ok(ref v) => s.serialize_str(v), - Err(ref v) => Bytes::from(&v.0[..]).serialize(s), - } - } - Value::Binary(ref v) => Bytes::from(&v[..]).serialize(s), - Value::Array(ref array) => { - let mut state = s.serialize_seq(Some(array.len()))?; - for item in array { - state.serialize_element(item)?; - } - state.end() - } - Value::Map(ref map) => { - let mut state = s.serialize_map(Some(map.len()))?; - for &(ref key, ref val) in map { - state.serialize_entry(key, val)?; - } - state.end() - } - Value::Ext(ty, ref buf) => { - let mut state = s.serialize_seq(Some(2))?; - state.serialize_element(&ty)?; - state.serialize_element(buf)?; - state.end() - } - } +use super::{Error, ValueExt}; + +pub fn from_value(val: Value) -> Result + where T: for<'de> Deserialize<'de> +{ + deserialize_from(val) +} + +pub fn deserialize_from<'de, T, D>(val: D) -> Result + where T: Deserialize<'de>, + D: Deserializer<'de, Error = Error> +{ + Deserialize::deserialize(val) +} + +impl de::Error for Error { + fn custom(msg: T) -> Self { + Error::Syntax(format!("{}", msg)) } } @@ -164,40 +138,105 @@ impl<'de> Deserialize<'de> for Value { } } -#[derive(Debug)] -pub enum Error { - Syntax(String), -} +impl<'de> Deserialize<'de> for ValueRef<'de> { + #[inline] + fn deserialize(de: D) -> Result + where D: Deserializer<'de> + { + struct ValueVisitor; -impl Display for Error { - fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { - match *self { - Error::Syntax(ref err) => write!(fmt, "{}: {}", error::Error::description(self), err) - } - } -} + impl<'de> de::Visitor<'de> for ValueVisitor { + type Value = ValueRef<'de>; -impl error::Error for Error { - fn description(&self) -> &str { - "error while decoding value" - } + fn expecting(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { + "any valid MessagePack value".fmt(fmt) + } - fn cause(&self) -> Option<&error::Error> { - match *self { - Error::Syntax(..) => None, - } - } -} + #[inline] + fn visit_some(self, de: D) -> Result + where D: Deserializer<'de> + { + Deserialize::deserialize(de) + } -impl de::Error for Error { - fn custom(msg: T) -> Self { - Error::Syntax(format!("{}", msg)) - } -} + #[inline] + fn visit_none(self) -> Result { + Ok(ValueRef::Nil) + } -impl ser::Error for Error { - fn custom(msg: T) -> Self { - Error::Syntax(format!("{}", msg)) + #[inline] + fn visit_unit(self) -> Result { + Ok(ValueRef::Nil) + } + + #[inline] + fn visit_bool(self, value: bool) -> Result { + Ok(ValueRef::Boolean(value)) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(ValueRef::from(value)) + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(ValueRef::from(value)) + } + + #[inline] + fn visit_f32(self, value: f32) -> Result { + Ok(ValueRef::F32(value)) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result { + Ok(ValueRef::F64(value)) + } + + #[inline] + fn visit_borrowed_str(self, value: &'de str) -> Result + where E: de::Error + { + Ok(ValueRef::String(Utf8StringRef::from(value))) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqAccess<'de> + { + let mut vec = Vec::new(); + + while let Some(elem) = visitor.next_element()? { + vec.push(elem); + } + + Ok(ValueRef::Array(vec)) + } + + #[inline] + fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result + where E: de::Error + { + Ok(ValueRef::Binary(v)) + } + + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where V: de::MapAccess<'de> + { + let mut vec = Vec::new(); + + while let Some(key) = visitor.next_key()? { + let val = visitor.next_value()?; + vec.push((key, val)); + } + + Ok(ValueRef::Map(vec)) + } + } + + de.deserialize_any(ValueVisitor) } } @@ -228,7 +267,7 @@ impl<'de> Deserializer<'de> for Value { Value::Binary(v) => visitor.visit_byte_buf(v), Value::Array(v) => { let len = v.len(); - let mut de = SeqDeserializer::new(v); + let mut de = SeqDeserializer::new(v.into_iter()); let seq = visitor.visit_seq(&mut de)?; if de.iter.len() == 0 { Ok(seq) @@ -238,7 +277,7 @@ impl<'de> Deserializer<'de> for Value { } Value::Map(v) => { let len = v.len(); - let mut de = MapAccess::new(v); + let mut de = MapDeserializer::new(v.into_iter()); let map = visitor.visit_map(&mut de)?; if de.iter.len() == 0 { Ok(map) @@ -292,93 +331,309 @@ impl<'de> Deserializer<'de> for Value { } } -struct SeqDeserializer { - iter: IntoIter, -} - -impl SeqDeserializer { - fn new(vec: Vec) -> Self { - SeqDeserializer { - iter: vec.into_iter(), - } - } -} - -impl<'de, V: Deserializer<'de, Error = Error>> SeqAccess<'de> for SeqDeserializer { +impl<'de> Deserializer<'de> for ValueRef<'de> { type Error = Error; - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> { - match self.iter.next() { - Some(val) => seed.deserialize(val).map(Some), - None => Ok(None), + match self { + ValueRef::Nil => visitor.visit_unit(), + ValueRef::Boolean(v) => visitor.visit_bool(v), + ValueRef::Integer(Integer { n }) => { + match n { + IntPriv::PosInt(v) => visitor.visit_u64(v), + IntPriv::NegInt(v) => visitor.visit_i64(v) + } + } + ValueRef::F32(v) => visitor.visit_f32(v), + ValueRef::F64(v) => visitor.visit_f64(v), + ValueRef::String(v) => { + match v.s { + Ok(v) => visitor.visit_borrowed_str(v), + Err(v) => visitor.visit_borrowed_bytes(v.0), + } + } + ValueRef::Binary(v) => visitor.visit_borrowed_bytes(v), + ValueRef::Array(v) => { + let len = v.len(); + let mut de = SeqDeserializer::new(v.into_iter()); + let seq = visitor.visit_seq(&mut de)?; + if de.iter.len() == 0 { + Ok(seq) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + ValueRef::Map(v) => { + let len = v.len(); + let mut de = MapDeserializer::new(v.into_iter()); + let map = visitor.visit_map(&mut de)?; + if de.iter.len() == 0 { + Ok(map) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in map")) + } + } + ValueRef::Ext(..) => { + unimplemented!(); + } } } - fn size_hint(&self) -> Option { - None + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + ValueBase::deserialize_option(self, visitor) } -} - -impl<'de, U: Deserializer<'de, Error = Error>> Deserializer<'de> for SeqDeserializer { - type Error = Error; #[inline] - fn deserialize_any(mut self, visitor: V) -> Result + fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = visitor.visit_seq(&mut self)?; - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } + ValueBase::deserialize_enum(self, visitor) } - forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + #[inline] + fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + where V: Visitor<'de> + { + ValueBase::deserialize_newtype_struct(self, visitor) } -} -struct MapAccess { - val: Option, - iter: IntoIter<(U, U)>, -} + #[inline] + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where V: Visitor<'de> + { + ValueBase::deserialize_unit_struct(self, visitor) + } -impl MapAccess { - fn new(map: Vec<(V, V)>) -> Self { - MapAccess { - val: None, - iter: map.into_iter(), - } + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + bytes byte_buf map tuple_struct struct + identifier tuple ignored_any } } -impl<'de, U: Deserializer<'de, Error = Error>> de::MapAccess<'de> for MapAccess { +impl<'de> Deserializer<'de> for &'de ValueRef<'de> { type Error = Error; - fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: DeserializeSeed<'de> + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> { - match self.iter.next() { - Some((key, val)) => { - self.val = Some(val); - seed.deserialize(key).map(Some) - } - None => Ok(None), - } - } - - fn next_value_seed(&mut self, seed: T) -> Result + match *self { + ValueRef::Nil => visitor.visit_unit(), + ValueRef::Boolean(v) => visitor.visit_bool(v), + ValueRef::Integer(Integer { n }) => { + match n { + IntPriv::PosInt(v) => visitor.visit_u64(v), + IntPriv::NegInt(v) => visitor.visit_i64(v) + } + } + ValueRef::F32(v) => visitor.visit_f32(v), + ValueRef::F64(v) => visitor.visit_f64(v), + ValueRef::String(v) => { + match v.s { + Ok(v) => visitor.visit_borrowed_str(v), + Err(v) => visitor.visit_borrowed_bytes(v.0), + } + } + ValueRef::Binary(v) => visitor.visit_borrowed_bytes(v), + ValueRef::Array(ref v) => { + let len = v.len(); + let mut de = SeqDeserializer::new(v.into_iter()); + let seq = visitor.visit_seq(&mut de)?; + if de.iter.len() == 0 { + Ok(seq) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + ValueRef::Map(ref v) => { + let len = v.len(); + let mut de = MapRefDeserializer::new(v.into_iter()); + let map = visitor.visit_map(&mut de)?; + if de.iter.len() == 0 { + Ok(map) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in map")) + } + } + ValueRef::Ext(..) => { + unimplemented!(); + } + } + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + if let &ValueRef::Nil = self { + visitor.visit_none() + } else { + visitor.visit_some(self) + } + } + + #[inline] + fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result + where V: Visitor<'de> + { + match self { + &ValueRef::Array(ref v) => { + let len = v.len(); + let mut iter = v.into_iter(); + if !(len == 1 || len == 2) { + return Err(de::Error::invalid_length(len, &"array with one or two elements")); + } + + let id = match iter.next() { + Some(id) => deserialize_from(id)?, + None => { + return Err(de::Error::invalid_length(len, &"array with one or two elements")); + } + }; + + visitor.visit_enum(EnumRefDeserializer::new(id, iter.next())) + } + other => Err(de::Error::invalid_type(other.unexpected(), &"array, map or int")), + } + } + + #[inline] + fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + where V: Visitor<'de> + { + match self { + &ValueRef::Array(ref v) => { + let iter = v.into_iter(); + if iter.len() != 1 { + return Err(de::Error::invalid_length(iter.len(), &"array with one element")); + } + + visitor.visit_seq(SeqDeserializer::new(iter)) + } + other => Err(de::Error::invalid_type(other.unexpected(), &"array")), + } + } + + #[inline] + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where V: Visitor<'de> + { + match self { + &ValueRef::Array(ref v) => { + if v.len() == 0 { + visitor.visit_unit() + } else { + Err(de::Error::invalid_length(v.len(), &"empty array")) + } + } + other => Err(de::Error::invalid_type(other.unexpected(), &"empty array")), + } + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + bytes byte_buf map tuple_struct struct + identifier tuple ignored_any + } +} + +struct SeqDeserializer { + iter: I, +} + +impl SeqDeserializer { + fn new(iter: I) -> Self { + Self { iter: iter } + } +} + +impl<'de, I, U> SeqAccess<'de> for SeqDeserializer + where I: Iterator, + U: Deserializer<'de, Error = Error> +{ + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed<'de> + { + match self.iter.next() { + Some(val) => seed.deserialize(val).map(Some), + None => Ok(None), + } + } +} + +impl<'de, I, U> Deserializer<'de> for SeqDeserializer + where I: ExactSizeIterator, + U: Deserializer<'de, Error = Error> +{ + type Error = Error; + + #[inline] + fn deserialize_any(mut self, visitor: V) -> Result + where V: Visitor<'de> + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = visitor.visit_seq(&mut self)?; + let rem = self.iter.len(); + if rem == 0 { + Ok(ret) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq bytes byte_buf map unit_struct newtype_struct + tuple_struct struct identifier tuple enum ignored_any + } +} + +struct MapDeserializer { + val: Option, + iter: I, +} + +impl MapDeserializer { + fn new(iter: I) -> Self { + Self { + val: None, + iter: iter, + } + } +} + +impl<'de, I, U> de::MapAccess<'de> for MapDeserializer + where I: Iterator, + U: ValueBase<'de> +{ + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> + where T: DeserializeSeed<'de> + { + match self.iter.next() { + Some((key, val)) => { + self.val = Some(val); + seed.deserialize(key).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result where T: DeserializeSeed<'de> { match self.val.take() { @@ -386,13 +641,12 @@ impl<'de, U: Deserializer<'de, Error = Error>> de::MapAccess<'de> for MapAccess< None => Err(de::Error::custom("value is missing")), } } - - fn size_hint(&self) -> Option { - None - } } -impl<'de, U: Deserializer<'de, Error = Error>> Deserializer<'de> for MapAccess { +impl<'de, I, U> Deserializer<'de> for MapDeserializer + where I: Iterator, + U: ValueBase<'de> +{ type Error = Error; #[inline] @@ -409,8 +663,7 @@ impl<'de, U: Deserializer<'de, Error = Error>> Deserializer<'de> for MapAccess { +struct EnumDeserializer { id: u32, value: Option, } @@ -437,8 +690,7 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::EnumAccess<'de> for EnumDeserializer } } -#[derive(Debug)] -pub struct VariantDeserializer { +struct VariantDeserializer { value: Option, } @@ -449,10 +701,10 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeseri // Can accept only [u32]. match self.value { Some(v) => { - match v.as_array() { - Ok(ref v) if v.is_empty() => Ok(()), + match v.into_iter() { + Ok(ref v) if v.len() == 0 => Ok(()), Ok(..) => Err(de::Error::invalid_value(Unexpected::Seq, &"empty array")), - Err(unexpected) => Err(de::Error::invalid_value(unexpected, &"empty array")), + Err(v) => Err(de::Error::invalid_value(v.unexpected(), &"empty array")), } } None => Ok(()), @@ -465,12 +717,11 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeseri // Can accept both [u32, T...] and [u32, [T]] cases. match self.value { Some(v) => { - match v.into_array() { - Ok(v) => { - if v.len() > 1 { - seed.deserialize(SeqDeserializer::new(v)) + match v.into_iter() { + Ok(mut iter) => { + if iter.len() > 1 { + seed.deserialize(SeqDeserializer::new(iter)) } else { - let mut iter = v.into_iter(); let val = match iter.next() { Some(val) => seed.deserialize(val), None => return Err(de::Error::invalid_value(Unexpected::Seq, &"array with one element")), @@ -496,7 +747,7 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeseri // Can accept [u32, [T...]]. match self.value { Some(v) => { - match v.into_array() { + match v.into_iter() { Ok(v) => Deserializer::deserialize_any(SeqDeserializer::new(v), visitor), Err(v) => Err(de::Error::invalid_type(v.unexpected(), &"tuple variant")), } @@ -510,11 +761,11 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeseri { match self.value { Some(v) => { - match v.into_array() { - Ok(v) => Deserializer::deserialize_any(SeqDeserializer::new(v), visitor), + match v.into_iter() { + Ok(iter) => Deserializer::deserialize_any(SeqDeserializer::new(iter), visitor), Err(v) => { - match v.into_map() { - Ok(v) => Deserializer::deserialize_any(MapAccess::new(v), visitor), + match v.into_map_iter() { + Ok(iter) => Deserializer::deserialize_any(MapDeserializer::new(iter), visitor), Err(v) => Err(de::Error::invalid_type(v.unexpected(), &"struct variant")), } } @@ -525,526 +776,179 @@ impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeseri } } -pub trait ValueExt { - fn unexpected(&self) -> Unexpected; +pub struct MapRefDeserializer<'de> { + val: Option<&'de ValueRef<'de>>, + iter: Iter<'de, (ValueRef<'de>, ValueRef<'de>)>, } -impl ValueExt for Value { - fn unexpected(&self) -> Unexpected { - match *self { - Value::Nil => Unexpected::Unit, - Value::Boolean(v) => Unexpected::Bool(v), - Value::Integer(Integer { n }) => { - match n { - IntPriv::PosInt(v) => Unexpected::Unsigned(v), - IntPriv::NegInt(v) => Unexpected::Signed(v), - } - } - Value::F32(v) => Unexpected::Float(v as f64), - Value::F64(v) => Unexpected::Float(v), - Value::String(ref v) => { - match v.s { - Ok(ref v) => Unexpected::Str(v), - Err(ref v) => Unexpected::Bytes(&v.0[..]), - } - } - Value::Binary(ref v) => Unexpected::Bytes(v), - Value::Array(..) => Unexpected::Seq, - Value::Map(..) => Unexpected::Map, - Value::Ext(..) => Unexpected::Seq, +impl<'de> MapRefDeserializer<'de> { + fn new(iter: Iter<'de, (ValueRef<'de>, ValueRef<'de>)>) -> Self { + Self { + val: None, + iter: iter, } } } -impl<'a> ValueExt for ValueRef<'a> { - fn unexpected(&self) -> Unexpected { - match *self { - ValueRef::Nil => Unexpected::Unit, - ValueRef::Boolean(v) => Unexpected::Bool(v), - ValueRef::Integer(Integer { n }) => { - match n { - IntPriv::PosInt(v) => Unexpected::Unsigned(v), - IntPriv::NegInt(v) => Unexpected::Signed(v), - } - } - ValueRef::F32(v) => Unexpected::Float(v as f64), - ValueRef::F64(v) => Unexpected::Float(v), - ValueRef::String(ref v) => { - match v.s { - Ok(ref v) => Unexpected::Str(v), - Err(ref v) => Unexpected::Bytes(&v.0[..]), - } +impl<'de> de::MapAccess<'de> for MapRefDeserializer<'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> + where T: DeserializeSeed<'de> + { + match self.iter.next() { + Some(&(ref key, ref val)) => { + self.val = Some(val); + seed.deserialize(key).map(Some) } - ValueRef::Binary(ref v) => Unexpected::Bytes(v), - ValueRef::Array(..) => Unexpected::Seq, - ValueRef::Map(..) => Unexpected::Map, - ValueRef::Ext(..) => Unexpected::Seq, + None => Ok(None), } } -} - -pub fn from_value(val: Value) -> Result - where T: for<'de> Deserialize<'de> -{ - Deserialize::deserialize(val) -} -struct Serializer; - -/// Convert a `T` into `rmpv::Value` which is an enum that can represent any valid MessagePack data. -/// -/// This conversion can fail if `T`'s implementation of `Serialize` decides to fail. -/// -/// ```rust -/// # use rmpv::Value; -/// -/// let val = rmpv::ext::to_value("John Smith").unwrap(); -/// -/// assert_eq!(Value::String("John Smith".into()), val); -/// ``` -pub fn to_value(value: T) -> Result { - value.serialize(Serializer) + fn next_value_seed(&mut self, seed: T) -> Result + where T: DeserializeSeed<'de> + { + match self.val.take() { + Some(val) => seed.deserialize(val), + None => Err(de::Error::custom("value is missing")), + } + } } -impl ser::Serializer for Serializer { - type Ok = Value; +impl<'de> Deserializer<'de> for MapRefDeserializer<'de> { type Error = Error; - type SerializeSeq = SerializeVec; - type SerializeTuple = SerializeVec; - type SerializeTupleStruct = SerializeVec; - type SerializeTupleVariant = SerializeTupleVariant; - type SerializeMap = DefaultSerializeMap; - type SerializeStruct = SerializeVec; - type SerializeStructVariant = SerializeStructVariant; - - #[inline] - fn serialize_bool(self, val: bool) -> Result { - Ok(Value::Boolean(val)) - } - #[inline] - fn serialize_i8(self, val: i8) -> Result { - self.serialize_i64(val as i64) + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> + { + visitor.visit_map(self) } - #[inline] - fn serialize_i16(self, val: i16) -> Result { - self.serialize_i64(val as i64) + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq bytes byte_buf map unit_struct newtype_struct + tuple_struct struct identifier tuple enum ignored_any } +} - #[inline] - fn serialize_i32(self, val: i32) -> Result { - self.serialize_i64(val as i64) - } +pub struct EnumRefDeserializer<'de> { + id: u32, + value: Option<&'de ValueRef<'de>>, +} - #[inline] - fn serialize_i64(self, val: i64) -> Result { - Ok(Value::from(val)) +impl<'de> EnumRefDeserializer<'de> { + pub fn new(id: u32, value: Option<&'de ValueRef<'de>>) -> Self { + Self { + id: id, + value: value, + } } +} - #[inline] - fn serialize_u8(self, val: u8) -> Result { - self.serialize_u64(val as u64) - } +impl<'de> de::EnumAccess<'de> for EnumRefDeserializer<'de> { + type Error = Error; + type Variant = VariantRefDeserializer<'de>; - #[inline] - fn serialize_u16(self, val: u16) -> Result { - self.serialize_u64(val as u64) + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where V: de::DeserializeSeed<'de> + { + let variant = self.id.into_deserializer(); + let visitor = VariantRefDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) } +} - #[inline] - fn serialize_u32(self, val: u32) -> Result { - self.serialize_u64(val as u64) - } +pub struct VariantRefDeserializer<'de> { + value: Option<&'de ValueRef<'de>>, +} - #[inline] - fn serialize_u64(self, val: u64) -> Result { - Ok(Value::from(val)) - } +impl<'de> de::VariantAccess<'de> for VariantRefDeserializer<'de> { + type Error = Error; - #[inline] - fn serialize_f32(self, val: f32) -> Result { - Ok(Value::F32(val)) - } - - #[inline] - fn serialize_f64(self, val: f64) -> Result { - Ok(Value::F64(val)) - } - - #[inline] - fn serialize_char(self, val: char) -> Result { - let mut buf = String::new(); - buf.push(val); - self.serialize_str(&buf) - } - - #[inline] - fn serialize_str(self, val: &str) -> Result { - Ok(Value::String(val.into())) - } - - #[inline] - fn serialize_bytes(self, val: &[u8]) -> Result { - Ok(Value::Binary(val.into())) - } - - #[inline] - fn serialize_unit(self) -> Result { - Ok(Value::Nil) - } - - #[inline] - fn serialize_unit_struct(self, _name: &'static str) -> Result { - Ok(Value::Array(Vec::new())) - } - - #[inline] - fn serialize_unit_variant(self, _name: &'static str, idx: u32, _variant: &'static str) -> Result { - let vec = vec![ - Value::from(idx), - Value::Array(Vec::new()) - ]; - Ok(Value::Array(vec)) - } - - #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result - where T: Serialize - { - Ok(Value::Array(vec![to_value(value)?])) - } - - fn serialize_newtype_variant(self, _name: &'static str, idx: u32, _variant: &'static str, value: &T) -> Result - where T: Serialize - { - let vec = vec![ - Value::from(idx), - Value::Array(vec![to_value(value)?]), - ]; - Ok(Value::Array(vec)) - } - - #[inline] - fn serialize_none(self) -> Result { - self.serialize_unit() - } - - #[inline] - fn serialize_some(self, value: &T) -> Result - where T: Serialize - { - value.serialize(self) - } - - fn serialize_seq(self, len: Option) -> Result { - let se = SerializeVec { - vec: Vec::with_capacity(len.unwrap_or(0)) - }; - Ok(se) - } - - fn serialize_tuple(self, len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { - let se = SerializeTupleVariant { - idx: idx, - vec: Vec::with_capacity(len), - }; - Ok(se) - } - - fn serialize_map(self, len: Option) -> Result { - let se = DefaultSerializeMap { - map: Vec::with_capacity(len.unwrap_or(0)), - next_key: None, - }; - Ok(se) - } - - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - self.serialize_tuple_struct(name, len) - } - - fn serialize_struct_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { - let se = SerializeStructVariant { - idx: idx, - vec: Vec::with_capacity(len), - }; - Ok(se) - } -} - -#[doc(hidden)] -pub struct SerializeVec { - vec: Vec, -} - -/// Default implementation for tuple variant serialization. It packs given enums as a tuple of an -/// index with a tuple of arguments. -#[doc(hidden)] -pub struct SerializeTupleVariant { - idx: u32, - vec: Vec, -} - -#[doc(hidden)] -pub struct DefaultSerializeMap { - map: Vec<(Value, Value)>, - next_key: Option, -} - -#[doc(hidden)] -pub struct SerializeStructVariant { - idx: u32, - vec: Vec, -} - -impl SerializeSeq for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where T: Serialize - { - self.vec.push(to_value(&value)?); - Ok(()) - } - - fn end(self) -> Result { - Ok(Value::Array(self.vec)) - } -} - -impl SerializeTuple for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where T: Serialize - { - ser::SerializeSeq::serialize_element(self, value) - } - - fn end(self) -> Result { - ser::SerializeSeq::end(self) - } -} - -impl SerializeTupleStruct for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where T: Serialize - { - ser::SerializeSeq::serialize_element(self, value) - } - - fn end(self) -> Result { - ser::SerializeSeq::end(self) - } -} - -impl ser::SerializeTupleVariant for SerializeTupleVariant { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where T: Serialize - { - self.vec.push(to_value(&value)?); - Ok(()) - } - - fn end(self) -> Result { - Ok(Value::Array(vec![Value::from(self.idx), Value::Array(self.vec)])) - } -} - -impl ser::SerializeMap for DefaultSerializeMap { - type Ok = Value; - type Error = Error; - - fn serialize_key(&mut self, key: &T) -> Result<(), Error> - where T: Serialize - { - self.next_key = Some(to_value(key)?); - Ok(()) - } - - fn serialize_value(&mut self, value: &T) -> Result<(), Error> - where T: ser::Serialize - { - // Panic because this indicates a bug in the program rather than an - // expected failure. - let key = self.next_key.take() - .expect("`serialize_value` called before `serialize_key`"); - self.map.push((key, to_value(&value)?)); - Ok(()) - } - - fn end(self) -> Result { - Ok(Value::Map(self.map)) + fn unit_variant(self) -> Result<(), Error> { + // Can accept only [u32]. + match self.value { + Some(&ValueRef::Array(ref v)) => { + if v.len() == 0 { + Ok(()) + } else { + Err(de::Error::invalid_value(Unexpected::Seq, &"empty array")) + } + } + Some(v) => Err(de::Error::invalid_value(v.unexpected(), &"empty array")), + None => Ok(()), + } } -} -impl SerializeStruct for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> - where T: Serialize + fn newtype_variant_seed(self, seed: T) -> Result + where T: de::DeserializeSeed<'de> { - ser::SerializeSeq::serialize_element(self, value) - } + // Can accept both [u32, T...] and [u32, [T]] cases. + match self.value { + Some(&ValueRef::Array(ref v)) => { + let len = v.len(); + let mut iter = v.into_iter(); + if len > 1 { + seed.deserialize(SeqDeserializer::new(iter)) + } else { + let val = match iter.next() { + Some(val) => seed.deserialize(val), + None => return Err(de::Error::invalid_length(len, &"array with one element")), + }; - fn end(self) -> Result { - ser::SerializeSeq::end(self) + if iter.next().is_some() { + Err(de::Error::invalid_length(len, &"array with one element")) + } else { + val + } + } + } + Some(v) => seed.deserialize(v), + None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")), + } } -} -impl ser::SerializeStructVariant for SerializeStructVariant { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> - where T: Serialize + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where V: Visitor<'de> { - self.vec.push(to_value(&value)?); - Ok(()) - } - - fn end(self) -> Result { - Ok(Value::Array(vec![Value::from(self.idx), Value::Array(self.vec)])) + // Can accept [u32, [T...]]. + match self.value { + Some(&ValueRef::Array(ref v)) => { + Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) + } + Some(v) => Err(de::Error::invalid_type(v.unexpected(), &"tuple variant")), + None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) + } } -} -impl<'de> Deserialize<'de> for ValueRef<'de> { - #[inline] - fn deserialize(de: D) -> Result - where D: Deserializer<'de> + fn struct_variant(self, _fields: &'static [&'static str], visitor: V) -> Result + where V: Visitor<'de>, { - struct ValueVisitor; - - impl<'de> de::Visitor<'de> for ValueVisitor { - type Value = ValueRef<'de>; - - fn expecting(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { - "any valid MessagePack value".fmt(fmt) - } - - #[inline] - fn visit_some(self, de: D) -> Result - where D: Deserializer<'de> - { - Deserialize::deserialize(de) - } - - #[inline] - fn visit_none(self) -> Result { -// Ok(ValueRef::Nil) - unimplemented!(); - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(ValueRef::Nil) - } - - #[inline] - fn visit_bool(self, value: bool) -> Result { - Ok(ValueRef::Boolean(value)) - } - - #[inline] - fn visit_u64(self, value: u64) -> Result { - Ok(ValueRef::from(value)) - } - - #[inline] - fn visit_i64(self, value: i64) -> Result { - Ok(ValueRef::from(value)) - } - - #[inline] - fn visit_f32(self, value: f32) -> Result { - Ok(ValueRef::F32(value)) - } - - #[inline] - fn visit_f64(self, value: f64) -> Result { - Ok(ValueRef::F64(value)) - } - - #[inline] - fn visit_borrowed_str(self, value: &'de str) -> Result - where E: de::Error - { - Ok(ValueRef::String(Utf8StringRef::from(value))) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where V: SeqAccess<'de> - { - let mut vec = Vec::new(); - - while let Some(elem) = visitor.next_element()? { - vec.push(elem); - } - - Ok(ValueRef::Array(vec)) - } - - #[inline] - fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result - where E: de::Error - { - Ok(ValueRef::Binary(v)) + match self.value { + Some(&ValueRef::Array(ref v)) => { + Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) } - - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where V: de::MapAccess<'de> - { - let mut vec = Vec::new(); - - while let Some(key) = visitor.next_key()? { - let val = visitor.next_value()?; - vec.push((key, val)); - } - - Ok(ValueRef::Map(vec)) + Some(&ValueRef::Map(ref v)) => { + Deserializer::deserialize_any(MapRefDeserializer::new(v.into_iter()), visitor) } + Some(v) => Err(de::Error::invalid_type(v.unexpected(), &"struct variant")), + None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) } - - de.deserialize_any(ValueVisitor) } } -pub fn deserialize_from<'de, T, D>(val: D) -> Result - where T: Deserialize<'de>, - D: Deserializer<'de, Error = Error> -{ - Deserialize::deserialize(val) -} +// TODO: Ugly hack. Needed for avoiding copy-pasting similar code, but I don't like it. +trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { + type Item: ValueBase<'de>; + type Iter: ExactSizeIterator; + type MapIter: Iterator; + type MapDeserializer: Deserializer<'de>; -pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { fn is_nil(&self) -> bool; - fn as_array(&self) -> Result<&Vec, Unexpected>; - - fn into_array(self) -> Result, Self>; - - fn into_map(self) -> Result, Self>; + fn into_iter(self) -> Result; + fn into_map_iter(self) -> Result; #[inline] fn deserialize_option(self, visitor: V) -> Result @@ -1061,12 +965,10 @@ pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { fn deserialize_enum(self, visitor: V) -> Result where V: Visitor<'de> { - match self.into_array() { - Ok(v) => { - let mut iter = v.into_iter(); - + match self.into_iter() { + Ok(mut iter) => { if !(iter.len() == 1 || iter.len() == 2) { - return Err(de::Error::invalid_value(Unexpected::Seq, &"array with one or two elements")); + return Err(de::Error::invalid_length(iter.len(), &"array with one or two elements")); } let id = match iter.next() { @@ -1076,10 +978,7 @@ pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { } }; - visitor.visit_enum(EnumDeserializer { - id: id, - value: iter.next(), - }) + visitor.visit_enum(EnumDeserializer::new(id, iter.next())) } Err(other) => { Err(de::Error::invalid_type(other.unexpected(), &"array, map or int")) @@ -1091,9 +990,8 @@ pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { fn deserialize_newtype_struct(self, visitor: V) -> Result where V: Visitor<'de> { - match self.into_array() { - Ok(v) => { - let iter = v.into_iter(); + match self.into_iter() { + Ok(iter) => { if iter.len() != 1 { return Err(de::Error::invalid_value(Unexpected::Seq, &"array with one element")); } @@ -1110,9 +1008,9 @@ pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { fn deserialize_unit_struct(self, visitor: V) -> Result where V: Visitor<'de> { - match self.into_array() { - Ok(v) => { - if v.is_empty() { + match self.into_iter() { + Ok(iter) => { + if iter.len() == 0 { visitor.visit_unit() } else { Err(de::Error::invalid_type(Unexpected::Seq, &"empty array")) @@ -1124,6 +1022,11 @@ pub trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { } impl<'de> ValueBase<'de> for Value { + type Item = Value; + type Iter = IntoIter; + type MapIter = IntoIter<(Value, Value)>; + type MapDeserializer = MapDeserializer; + #[inline] fn is_nil(&self) -> bool { if let &Value::Nil = self { @@ -1134,31 +1037,28 @@ impl<'de> ValueBase<'de> for Value { } #[inline] - fn as_array(&self) -> Result<&Vec, Unexpected> { - match self { - &Value::Array(ref v) => Ok(v), - other => Err(other.unexpected()) - } - } - - #[inline] - fn into_array(self) -> Result, Self> { + fn into_iter(self) -> Result { match self { - Value::Array(v) => Ok(v), + Value::Array(v) => Ok(v.into_iter()), other => Err(other) } } #[inline] - fn into_map(self) -> Result, Self> { + fn into_map_iter(self) -> Result { match self { - Value::Map(v) => Ok(v), + Value::Map(v) => Ok(v.into_iter()), other => Err(other) } } } impl<'de> ValueBase<'de> for ValueRef<'de> { + type Item = ValueRef<'de>; + type Iter = IntoIter>; + type MapIter = IntoIter<(ValueRef<'de>, ValueRef<'de>)>; + type MapDeserializer = MapDeserializer; + #[inline] fn is_nil(&self) -> bool { if let &ValueRef::Nil = self { @@ -1169,117 +1069,18 @@ impl<'de> ValueBase<'de> for ValueRef<'de> { } #[inline] - fn as_array(&self) -> Result<&Vec, Unexpected> { + fn into_iter(self) -> Result { match self { - &ValueRef::Array(ref v) => Ok(v), - other => Err(other.unexpected()) - } - } - - #[inline] - fn into_array(self) -> Result, Self> { - match self { - ValueRef::Array(v) => Ok(v), + ValueRef::Array(v) => Ok(v.into_iter()), other => Err(other) } } #[inline] - fn into_map(self) -> Result, Self> { + fn into_map_iter(self) -> Result { match self { - ValueRef::Map(v) => Ok(v), + ValueRef::Map(v) => Ok(v.into_iter()), other => Err(other) } } } - -impl<'de> Deserializer<'de> for ValueRef<'de> { - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where V: Visitor<'de> - { - match self { - ValueRef::Nil => visitor.visit_unit(), - ValueRef::Boolean(v) => visitor.visit_bool(v), - ValueRef::Integer(Integer { n }) => { - match n { - IntPriv::PosInt(v) => visitor.visit_u64(v), - IntPriv::NegInt(v) => visitor.visit_i64(v) - } - } - ValueRef::F32(v) => visitor.visit_f32(v), - ValueRef::F64(v) => visitor.visit_f64(v), - ValueRef::String(v) => { - match v.s { - Ok(v) => visitor.visit_borrowed_str(v), - Err(v) => visitor.visit_borrowed_bytes(v.0), - } - } - ValueRef::Binary(v) => visitor.visit_borrowed_bytes(v), - ValueRef::Array(v) => { - let len = v.len(); - let mut de = SeqDeserializer::new(v); - let seq = visitor.visit_seq(&mut de)?; - if de.iter.len() == 0 { - Ok(seq) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } - ValueRef::Map(v) => { - let len = v.len(); - let mut de = MapAccess::new(v); - let map = visitor.visit_map(&mut de)?; - if de.iter.len() == 0 { - Ok(map) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in map")) - } - } - ValueRef::Ext(..) => { - // TODO: [i8, [u8]] can be represented as: - // - (0i8, Vec), - // - struct F(i8, Vec), - // - struct F {ty: i8, val: Vec} - // - enum F{ A(Vec), B { name: Vec } } - unimplemented!(); - } - } - } - - #[inline] - fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> - { - ValueBase::deserialize_option(self, visitor) - } - - #[inline] - fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result - where V: Visitor<'de> - { - ValueBase::deserialize_enum(self, visitor) - } - - #[inline] - fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result - where V: Visitor<'de> - { - ValueBase::deserialize_newtype_struct(self, visitor) - } - - #[inline] - fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result - where V: Visitor<'de> - { - ValueBase::deserialize_unit_struct(self, visitor) - } - - forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - bytes byte_buf map tuple_struct struct - identifier tuple ignored_any - } -} diff --git a/rmpv/src/ext/mod.rs b/rmpv/src/ext/mod.rs new file mode 100644 index 00000000..e20ad6d7 --- /dev/null +++ b/rmpv/src/ext/mod.rs @@ -0,0 +1,95 @@ +use std::error; +use std::fmt::{self, Display, Formatter}; + +use serde::de::Unexpected; + +use {Integer, IntPriv, Value, ValueRef}; + +pub use self::de::{deserialize_from, from_value, EnumRefDeserializer}; +pub use self::se::to_value; + +mod de; +mod se; + +#[derive(Debug)] +pub enum Error { + Syntax(String), +} + +impl Display for Error { + fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { + match *self { + Error::Syntax(ref err) => write!(fmt, "{}: {}", error::Error::description(self), err) + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + "error while decoding value" + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + Error::Syntax(..) => None, + } + } +} + +trait ValueExt { + fn unexpected(&self) -> Unexpected; +} + +impl ValueExt for Value { + fn unexpected(&self) -> Unexpected { + match *self { + Value::Nil => Unexpected::Unit, + Value::Boolean(v) => Unexpected::Bool(v), + Value::Integer(Integer { n }) => { + match n { + IntPriv::PosInt(v) => Unexpected::Unsigned(v), + IntPriv::NegInt(v) => Unexpected::Signed(v), + } + } + Value::F32(v) => Unexpected::Float(v as f64), + Value::F64(v) => Unexpected::Float(v), + Value::String(ref v) => { + match v.s { + Ok(ref v) => Unexpected::Str(v), + Err(ref v) => Unexpected::Bytes(&v.0[..]), + } + } + Value::Binary(ref v) => Unexpected::Bytes(v), + Value::Array(..) => Unexpected::Seq, + Value::Map(..) => Unexpected::Map, + Value::Ext(..) => Unexpected::Seq, + } + } +} + +impl<'a> ValueExt for ValueRef<'a> { + fn unexpected(&self) -> Unexpected { + match *self { + ValueRef::Nil => Unexpected::Unit, + ValueRef::Boolean(v) => Unexpected::Bool(v), + ValueRef::Integer(Integer { n }) => { + match n { + IntPriv::PosInt(v) => Unexpected::Unsigned(v), + IntPriv::NegInt(v) => Unexpected::Signed(v), + } + } + ValueRef::F32(v) => Unexpected::Float(v as f64), + ValueRef::F64(v) => Unexpected::Float(v), + ValueRef::String(ref v) => { + match v.s { + Ok(ref v) => Unexpected::Str(v), + Err(ref v) => Unexpected::Bytes(&v.0[..]), + } + } + ValueRef::Binary(ref v) => Unexpected::Bytes(v), + ValueRef::Array(..) => Unexpected::Seq, + ValueRef::Map(..) => Unexpected::Map, + ValueRef::Ext(..) => Unexpected::Seq, + } + } +} diff --git a/rmpv/src/ext/se.rs b/rmpv/src/ext/se.rs new file mode 100644 index 00000000..e868e326 --- /dev/null +++ b/rmpv/src/ext/se.rs @@ -0,0 +1,399 @@ +use std::fmt::Display; + +use serde::Serialize; +use serde::ser::{self, SerializeSeq, SerializeTuple, SerializeTupleStruct, SerializeMap, SerializeStruct}; +use serde_bytes::Bytes; + +use {Integer, IntPriv, Value}; + +use super::Error; + +impl Serialize for Value { + fn serialize(&self, s: S) -> Result + where S: ser::Serializer + { + match *self { + Value::Nil => s.serialize_unit(), + Value::Boolean(v) => s.serialize_bool(v), + Value::Integer(Integer { n }) => { + match n { + IntPriv::PosInt(n) => s.serialize_u64(n), + IntPriv::NegInt(n) => s.serialize_i64(n), + } + } + Value::F32(v) => s.serialize_f32(v), + Value::F64(v) => s.serialize_f64(v), + Value::String(ref v) => { + match v.s { + Ok(ref v) => s.serialize_str(v), + Err(ref v) => Bytes::from(&v.0[..]).serialize(s), + } + } + Value::Binary(ref v) => Bytes::from(&v[..]).serialize(s), + Value::Array(ref array) => { + let mut state = s.serialize_seq(Some(array.len()))?; + for item in array { + state.serialize_element(item)?; + } + state.end() + } + Value::Map(ref map) => { + let mut state = s.serialize_map(Some(map.len()))?; + for &(ref key, ref val) in map { + state.serialize_entry(key, val)?; + } + state.end() + } + Value::Ext(ty, ref buf) => { + let mut state = s.serialize_seq(Some(2))?; + state.serialize_element(&ty)?; + state.serialize_element(buf)?; + state.end() + } + } + } +} + +impl ser::Error for Error { + fn custom(msg: T) -> Self { + Error::Syntax(format!("{}", msg)) + } +} + +struct Serializer; + +/// Convert a `T` into `rmpv::Value` which is an enum that can represent any valid MessagePack data. +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to fail. +/// +/// ```rust +/// # use rmpv::Value; +/// +/// let val = rmpv::ext::to_value("John Smith").unwrap(); +/// +/// assert_eq!(Value::String("John Smith".into()), val); +/// ``` +pub fn to_value(value: T) -> Result { + value.serialize(Serializer) +} + +impl ser::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = DefaultSerializeMap; + type SerializeStruct = SerializeVec; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, val: bool) -> Result { + Ok(Value::Boolean(val)) + } + + #[inline] + fn serialize_i8(self, val: i8) -> Result { + self.serialize_i64(val as i64) + } + + #[inline] + fn serialize_i16(self, val: i16) -> Result { + self.serialize_i64(val as i64) + } + + #[inline] + fn serialize_i32(self, val: i32) -> Result { + self.serialize_i64(val as i64) + } + + #[inline] + fn serialize_i64(self, val: i64) -> Result { + Ok(Value::from(val)) + } + + #[inline] + fn serialize_u8(self, val: u8) -> Result { + self.serialize_u64(val as u64) + } + + #[inline] + fn serialize_u16(self, val: u16) -> Result { + self.serialize_u64(val as u64) + } + + #[inline] + fn serialize_u32(self, val: u32) -> Result { + self.serialize_u64(val as u64) + } + + #[inline] + fn serialize_u64(self, val: u64) -> Result { + Ok(Value::from(val)) + } + + #[inline] + fn serialize_f32(self, val: f32) -> Result { + Ok(Value::F32(val)) + } + + #[inline] + fn serialize_f64(self, val: f64) -> Result { + Ok(Value::F64(val)) + } + + #[inline] + fn serialize_char(self, val: char) -> Result { + let mut buf = String::new(); + buf.push(val); + self.serialize_str(&buf) + } + + #[inline] + fn serialize_str(self, val: &str) -> Result { + Ok(Value::String(val.into())) + } + + #[inline] + fn serialize_bytes(self, val: &[u8]) -> Result { + Ok(Value::Binary(val.into())) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Nil) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Ok(Value::Array(Vec::new())) + } + + #[inline] + fn serialize_unit_variant(self, _name: &'static str, idx: u32, _variant: &'static str) -> Result { + let vec = vec![ + Value::from(idx), + Value::Array(Vec::new()) + ]; + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where T: Serialize + { + Ok(Value::Array(vec![to_value(value)?])) + } + + fn serialize_newtype_variant(self, _name: &'static str, idx: u32, _variant: &'static str, value: &T) -> Result + where T: Serialize + { + let vec = vec![ + Value::from(idx), + Value::Array(vec![to_value(value)?]), + ]; + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where T: Serialize + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + let se = SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)) + }; + Ok(se) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { + let se = SerializeTupleVariant { + idx: idx, + vec: Vec::with_capacity(len), + }; + Ok(se) + } + + fn serialize_map(self, len: Option) -> Result { + let se = DefaultSerializeMap { + map: Vec::with_capacity(len.unwrap_or(0)), + next_key: None, + }; + Ok(se) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + self.serialize_tuple_struct(name, len) + } + + fn serialize_struct_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { + let se = SerializeStructVariant { + idx: idx, + vec: Vec::with_capacity(len), + }; + Ok(se) + } +} + +#[doc(hidden)] +pub struct SerializeVec { + vec: Vec, +} + +/// Default implementation for tuple variant serialization. It packs given enums as a tuple of an +/// index with a tuple of arguments. +#[doc(hidden)] +pub struct SerializeTupleVariant { + idx: u32, + vec: Vec, +} + +#[doc(hidden)] +pub struct DefaultSerializeMap { + map: Vec<(Value, Value)>, + next_key: Option, +} + +#[doc(hidden)] +pub struct SerializeStructVariant { + idx: u32, + vec: Vec, +} + +impl SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where T: Serialize + { + self.vec.push(to_value(&value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } +} + +impl SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where T: Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + ser::SerializeSeq::end(self) + } +} + +impl SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where T: Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where T: Serialize + { + self.vec.push(to_value(&value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(vec![Value::from(self.idx), Value::Array(self.vec)])) + } +} + +impl ser::SerializeMap for DefaultSerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where T: Serialize + { + self.next_key = Some(to_value(key)?); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where T: ser::Serialize + { + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = self.next_key.take() + .expect("`serialize_value` called before `serialize_key`"); + self.map.push((key, to_value(&value)?)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Map(self.map)) + } +} + +impl SerializeStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> + where T: Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> + where T: Serialize + { + self.vec.push(to_value(&value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(vec![Value::from(self.idx), Value::Array(self.vec)])) + } +}