From 1f5f21f225995b7d2af700c23de39b4d154506ee Mon Sep 17 00:00:00 2001 From: rolag Date: Thu, 27 Jul 2017 14:00:50 +0100 Subject: [PATCH 1/5] feat: Add as_ref() to Value and Utf8String (#139) --- rmpv/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++ rmpv/tests/decode_ref.rs | 1 + 2 files changed, 55 insertions(+) diff --git a/rmpv/src/lib.rs b/rmpv/src/lib.rs index 87995c78..4ab999ea 100644 --- a/rmpv/src/lib.rs +++ b/rmpv/src/lib.rs @@ -249,6 +249,13 @@ impl Utf8String { Err(err) => err.0, } } + + pub fn as_ref(&self) -> Utf8StringRef { + match self.s { + Ok(ref s) => Utf8StringRef { s: Ok(s.as_str()) }, + Err((ref buf, err)) => Utf8StringRef { s: Err((&buf[..], err)) }, + } + } } impl Display for Utf8String { @@ -410,6 +417,53 @@ pub enum Value { } impl Value { + /// Converts the current owned Value to a ValueRef. + /// + /// # Panics + /// + /// Panics in unable to allocate memory to keep all internal structures and buffers. + /// + /// # Examples + /// ``` + /// use rmpv::{Value, ValueRef}; + /// + /// let val = Value::Array(vec![ + /// Value::Nil, + /// Value::from(42), + /// Value::Array(vec![ + /// Value::String("le message".into()) + /// ]) + /// ]); + /// + /// let expected = ValueRef::Array(vec![ + /// ValueRef::Nil, + /// ValueRef::from(42), + /// ValueRef::Array(vec![ + /// ValueRef::from("le message"), + /// ]) + /// ]); + /// + /// assert_eq!(expected, val.as_ref()); + /// ``` + pub fn as_ref(&self) -> ValueRef { + match self { + &Value::Nil => ValueRef::Nil, + &Value::Boolean(val) => ValueRef::Boolean(val), + &Value::Integer(val) => ValueRef::Integer(val), + &Value::F32(val) => ValueRef::F32(val), + &Value::F64(val) => ValueRef::F64(val), + &Value::String(ref val) => ValueRef::String(val.as_ref()), + &Value::Binary(ref val) => ValueRef::Binary(val.as_slice()), + &Value::Array(ref val) => { + ValueRef::Array(val.iter().map(|v| v.as_ref()).collect()) + } + &Value::Map(ref val) => { + ValueRef::Map(val.iter().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref())).collect()) + } + &Value::Ext(ty, ref buf) => ValueRef::Ext(ty, buf.as_slice()), + } + } + /// Returns true if the `Value` is a Null. Returns false otherwise. /// /// # Examples diff --git a/rmpv/tests/decode_ref.rs b/rmpv/tests/decode_ref.rs index 4c580df0..0bd6f3d8 100644 --- a/rmpv/tests/decode_ref.rs +++ b/rmpv/tests/decode_ref.rs @@ -687,4 +687,5 @@ fn into_owned() { ]); assert_eq!(expected, val.to_owned()); + assert_eq!(expected.as_ref(), val); } From a155a72886ffc9be02ff87f601298705f66ab533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Hornick=C3=BD?= Date: Sun, 18 Jun 2017 17:46:09 +0200 Subject: [PATCH 2/5] Add _named methods for serializing structs as maps --- rmp-serde/src/encode.rs | 68 +++++++++++++++++++++++++++++++++++++++- rmp-serde/src/lib.rs | 20 +++--------- rmp-serde/tests/round.rs | 35 +++++++++++++++++++++ 3 files changed, 106 insertions(+), 17 deletions(-) diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs index de842478..484319be 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -92,6 +92,35 @@ impl VariantWriter for StructArrayWriter { } } +pub struct StructMapWriter; + +impl VariantWriter for StructMapWriter { + fn write_struct_len(&self, wr: &mut W, len: u32) -> Result + where + W: Write, + { + write_map_len(wr, len) + } + + fn write_field_name(&self, wr: &mut W, key: &str) -> Result<(), ValueWriteError> + where + W: Write, + { + write_str(wr, key) + } +} +impl Serializer { + /// Constructs a new `MessagePack` serializer whose output will be written to the writer + /// specified. + /// + /// # Note + /// + /// This is the default constructor, which returns a serializer that will serialize structs + /// using large named representation. + pub fn new_named(wr: W) -> Self { + Serializer::with(wr, StructMapWriter) + } +} /// Represents MessagePack serialization implementation. /// /// # Note @@ -128,6 +157,15 @@ impl Serializer { pub fn new(wr: W) -> Self { Serializer::with(wr, StructArrayWriter) } + pub fn compact(wr: W) -> Self { + Serializer::with(wr, StructArrayWriter) + } +} + +impl Serializer { + pub fn named(wr: W) -> Self { + Serializer::with(wr, StructMapWriter) + } } impl Serializer { @@ -438,6 +476,7 @@ impl<'a, W: Write, V: VariantWriter> serde::Serializer for &'a mut Serializer(wr: &mut W, val: &T) -> Result<(), Error> where W: Write, T: Serialize { - val.serialize(&mut Serializer::new(wr)) + val.serialize(&mut Serializer::compact(wr)) } +/// Serialize the given data structure as MessagePack into the I/O stream. +/// This function serializes structures as maps +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. +#[inline] +pub fn write_named(wr: &mut W, val: &T) -> Result<(), Error> +where + W: Write, + T: Serialize, +{ + val.serialize(&mut Serializer::named(wr)) +} /// Serialize the given data structure as a MessagePack byte vector. +/// This method uses compact representation, structs are serialized as arrays /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. #[inline] @@ -460,3 +512,17 @@ pub fn to_vec(val: &T) -> Result, Error> write(&mut buf, val)?; Ok(buf) } + +/// Serializes data structure into byte vector as a map +/// Resulting MessagePack message will contain field names +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. +#[inline] +pub fn to_vec_named(value: &T) -> Result, Error> +where + T: serde::Serialize, +{ + let mut buf = Vec::with_capacity(64); + value.serialize(&mut Serializer::named(&mut buf))?; + Ok(buf) +} diff --git a/rmp-serde/src/lib.rs b/rmp-serde/src/lib.rs index eea83021..cff13c35 100644 --- a/rmp-serde/src/lib.rs +++ b/rmp-serde/src/lib.rs @@ -269,19 +269,7 @@ impl<'de> Deserialize<'de> for RawRef<'de> { } } -/// Serializes a value to a byte vector. -pub fn to_vec(value: &T) -> Result, encode::Error> - where T: serde::Serialize -{ - let mut buf = Vec::with_capacity(64); - value.serialize(&mut Serializer::new(&mut buf))?; - Ok(buf) -} - -/// Deserializes a byte slice into the desired type. -pub fn from_slice<'a, T>(input: &'a [u8]) -> Result - where T: serde::Deserialize<'a> -{ - let mut de = Deserializer::from_slice(input); - serde::Deserialize::deserialize(&mut de) -} +// Reexport common functions from encode module +pub use encode::{write, write_named, to_vec, to_vec_named}; +// Reexport common functions from decode module +pub use decode::{from_slice, from_read}; diff --git a/rmp-serde/tests/round.rs b/rmp-serde/tests/round.rs index 76911525..1986fd6a 100644 --- a/rmp-serde/tests/round.rs +++ b/rmp-serde/tests/round.rs @@ -86,3 +86,38 @@ fn round_enum_with_nested_struct() { assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap()); } + +// Checks whether deserialization and serialization can both work with structs as maps +#[test] +fn round_struct_as_map() { + use std::io::Write; + use rmp::Marker; + use rmps::to_vec_named; + use rmps::decode::{from_read, from_slice}; + + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] + struct Dog1 { + name: String, + age: u16, + } + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] + struct Dog2 { + age: u16, + name: String, + } + + let dog1 = Dog1 { + name: "Frankie".into(), + age: 42, + }; + + let mut serialized: Vec = to_vec_named(&dog1).unwrap(); + let mut deserialized: Dog2 = from_slice(&serialized).unwrap(); + + let check = Dog1 { + age: deserialized.age, + name: deserialized.name, + }; + + assert_eq!(dog1, check); +} From 4377cc78e960b3f8b7bf1464da03db274a667479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Hornick=C3=BD?= Date: Sun, 18 Jun 2017 17:56:41 +0200 Subject: [PATCH 3/5] Remove duplicate methods --- rmp-serde/src/encode.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs index 484319be..6e519249 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -160,12 +160,7 @@ impl Serializer { pub fn compact(wr: W) -> Self { Serializer::with(wr, StructArrayWriter) } -} -impl Serializer { - pub fn named(wr: W) -> Self { - Serializer::with(wr, StructMapWriter) - } } impl Serializer { @@ -497,7 +492,7 @@ where W: Write, T: Serialize, { - val.serialize(&mut Serializer::named(wr)) + val.serialize(&mut Serializer::new_named(wr)) } /// Serialize the given data structure as a MessagePack byte vector. @@ -523,6 +518,6 @@ where T: serde::Serialize, { let mut buf = Vec::with_capacity(64); - value.serialize(&mut Serializer::named(&mut buf))?; + value.serialize(&mut Serializer::new_named(&mut buf))?; Ok(buf) } From d1edf30672d6ddb9a0d041ea14f0a9617db30a72 Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Sun, 23 Jul 2017 02:32:46 +0900 Subject: [PATCH 4/5] Strip formating from #133 --- rmp-serde/src/encode.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs index 6e519249..2743a635 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -160,7 +160,6 @@ impl Serializer { pub fn compact(wr: W) -> Self { Serializer::with(wr, StructArrayWriter) } - } impl Serializer { From a3195ee711b4ceddfb189fd9efd6caacbb1fbc8c Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Wed, 2 Aug 2017 13:26:38 +0900 Subject: [PATCH 5/5] Minimize difference from master --- rmp-serde/src/decode.rs | 8 ++++++++ rmp-serde/src/encode.rs | 1 + rmp-serde/src/lib.rs | 9 ++------- rmp-serde/tests/round.rs | 8 +++----- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/rmp-serde/src/decode.rs b/rmp-serde/src/decode.rs index 0b1da7ce..048653b9 100644 --- a/rmp-serde/src/decode.rs +++ b/rmp-serde/src/decode.rs @@ -606,3 +606,11 @@ pub fn from_read(rd: R) -> Result { Deserialize::deserialize(&mut Deserializer::new(rd)) } + +/// Deserializes a byte slice into the desired type. +pub fn from_slice<'a, T>(input: &'a [u8]) -> Result + where T: serde::Deserialize<'a> +{ + let mut de = Deserializer::from_slice(input); + serde::Deserialize::deserialize(&mut de) +} diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs index 2743a635..b0e76e59 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -520,3 +520,4 @@ where value.serialize(&mut Serializer::new_named(&mut buf))?; Ok(buf) } + diff --git a/rmp-serde/src/lib.rs b/rmp-serde/src/lib.rs index cff13c35..537c2154 100644 --- a/rmp-serde/src/lib.rs +++ b/rmp-serde/src/lib.rs @@ -68,8 +68,8 @@ use std::str::{self, Utf8Error}; use serde::de::{self, Deserialize}; -pub use decode::Deserializer; -pub use encode::Serializer; +pub use decode::{Deserializer, from_slice, from_read}; +pub use encode::{Serializer, to_vec, to_vec_named}; pub mod decode; pub mod encode; @@ -268,8 +268,3 @@ impl<'de> Deserialize<'de> for RawRef<'de> { de.deserialize_any(RawRefVisitor) } } - -// Reexport common functions from encode module -pub use encode::{write, write_named, to_vec, to_vec_named}; -// Reexport common functions from decode module -pub use decode::{from_slice, from_read}; diff --git a/rmp-serde/tests/round.rs b/rmp-serde/tests/round.rs index 1986fd6a..a5c80588 100644 --- a/rmp-serde/tests/round.rs +++ b/rmp-serde/tests/round.rs @@ -90,10 +90,8 @@ fn round_enum_with_nested_struct() { // Checks whether deserialization and serialization can both work with structs as maps #[test] fn round_struct_as_map() { - use std::io::Write; - use rmp::Marker; use rmps::to_vec_named; - use rmps::decode::{from_read, from_slice}; + use rmps::decode::from_slice; #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] struct Dog1 { @@ -111,8 +109,8 @@ fn round_struct_as_map() { age: 42, }; - let mut serialized: Vec = to_vec_named(&dog1).unwrap(); - let mut deserialized: Dog2 = from_slice(&serialized).unwrap(); + let serialized: Vec = to_vec_named(&dog1).unwrap(); + let deserialized: Dog2 = from_slice(&serialized).unwrap(); let check = Dog1 { age: deserialized.age,