diff --git a/rmp-serde/src/decode.rs b/rmp-serde/src/decode.rs index 968f02c4..ccd58715 100644 --- a/rmp-serde/src/decode.rs +++ b/rmp-serde/src/decode.rs @@ -78,9 +78,9 @@ impl From for Error { impl From for Error { fn from(err: ValueReadError) -> Error { match err { - ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), + ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), } } } @@ -88,9 +88,9 @@ impl From for Error { impl From for Error { fn from(err: NumValueReadError) -> Error { match err { - NumValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), + NumValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker), NumValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - NumValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), + NumValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), NumValueReadError::OutOfRange => Error::OutOfRange, } } @@ -100,9 +100,13 @@ impl<'a> From> for Error { fn from(err: DecodeStringError) -> Error { match err { DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), - DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()), + DecodeStringError::InvalidDataRead(..) => { + Error::Uncategorized("InvalidDataRead".to_string()) + } DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()), - DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()), + DecodeStringError::BufferSizeTooSmall(..) => { + Error::Uncategorized("BufferSizeTooSmall".to_string()) + } DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()), } } @@ -210,7 +214,7 @@ impl<'de, R: Read<'de>> Deserializer { } } - fn read_bin_data<'a>(&'a mut self, len: u32) -> Result, Error> { + fn read_bin_data<'a>(&'a mut self, len: u32) -> Result, Error> { self.rd.read_slice(len as usize).map_err(Error::InvalidDataRead) } @@ -275,9 +279,7 @@ impl<'de, 'a, R: Read<'de>> serde::Deserializer<'de> for &'a mut Deserializer Marker::I64 => visitor.visit_i64(rmp::decode::read_data_i64(&mut self.rd)?), Marker::F32 => visitor.visit_f32(rmp::decode::read_data_f32(&mut self.rd)?), Marker::F64 => visitor.visit_f64(rmp::decode::read_data_f64(&mut self.rd)?), - Marker::FixStr(len) => { - self.read_str_data(len as u32, visitor) - } + Marker::FixStr(len) => self.read_str_data(len as u32, visitor), Marker::Str8 => { let len = read_u8(&mut self.rd)?; self.read_str_data(len as u32, visitor) @@ -290,9 +292,7 @@ impl<'de, 'a, R: Read<'de>> serde::Deserializer<'de> for &'a mut Deserializer let len = read_u32(&mut self.rd)?; self.read_str_data(len as u32, visitor) } - Marker::FixArray(len) => { - self.read_array(len as u32, visitor) - } + Marker::FixArray(len) => self.read_array(len as u32, visitor), Marker::Array16 => { let len = read_u16(&mut self.rd)?; self.read_array(len as u32, visitor) @@ -301,9 +301,7 @@ impl<'de, 'a, R: Read<'de>> serde::Deserializer<'de> for &'a mut Deserializer let len = read_u32(&mut self.rd)?; self.read_array(len, visitor) } - Marker::FixMap(len) => { - self.read_map(len as u32, visitor) - } + Marker::FixMap(len) => self.read_map(len as u32, visitor), Marker::Map16 => { let len = read_u16(&mut self.rd)?; self.read_map(len as u32, visitor) @@ -343,7 +341,11 @@ impl<'de, 'a, R: Read<'de>> serde::Deserializer<'de> for &'a mut Deserializer } } - fn deserialize_enum(self, _name: &str, _variants: &[&str], visitor: V) -> Result + fn deserialize_enum(self, + _name: &str, + _variants: &[&str], + visitor: V) + -> Result where V: Visitor<'de> { match read_array_len(&mut self.rd)? { @@ -352,7 +354,10 @@ impl<'de, 'a, R: Read<'de>> serde::Deserializer<'de> for &'a mut Deserializer } } - fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + fn deserialize_newtype_struct(self, + _name: &'static str, + visitor: V) + -> Result where V: Visitor<'de> { match read_array_len(&mut self.rd)? { @@ -452,9 +457,7 @@ pub struct VariantAccess<'a, R: 'a> { impl<'a, R: 'a> VariantAccess<'a, R> { pub fn new(de: &'a mut Deserializer) -> Self { - VariantAccess { - de: de, - } + VariantAccess { de: de } } } @@ -463,7 +466,7 @@ impl<'de, 'a, R: Read<'de>> de::EnumAccess<'de> for VariantAccess<'a, R> { type Variant = Self; fn variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> - where V: de::DeserializeSeed<'de>, + where V: de::DeserializeSeed<'de> { use serde::de::IntoDeserializer; @@ -494,7 +497,10 @@ impl<'de, 'a, R: Read<'de>> de::VariantAccess<'de> for VariantAccess<'a, R> { de::Deserializer::deserialize_tuple(self.de, len, visitor) } - fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result + fn struct_variant(self, + fields: &'static [&'static str], + visitor: V) + -> Result where V: Visitor<'de> { de::Deserializer::deserialize_tuple(self.de, fields.len(), visitor) @@ -517,9 +523,7 @@ pub struct SliceReader<'a> { impl<'a> SliceReader<'a> { fn new(slice: &'a [u8]) -> Self { - SliceReader { - inner: slice, - } + SliceReader { inner: slice } } } @@ -527,7 +531,7 @@ impl<'de> Read<'de> for SliceReader<'de> { #[inline] fn read_slice<'a>(&'a mut self, len: usize) -> Result, io::Error> { if len > self.inner.len() { - return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF")) + return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF")); } let (a, b) = self.inner.split_at(len); self.inner = b; @@ -549,7 +553,7 @@ impl<'a> io::Read for SliceReader<'a> { struct ReadReader { inner: R, - buf: Vec + buf: Vec, } impl ReadReader { @@ -590,9 +594,11 @@ fn test_slice_read() { let mut rd = SliceReader::new(&buf[..]); assert_eq!(rd.read_slice(1).unwrap(), Reference::Borrowed(&[0][..])); - assert_eq!(rd.read_slice(6).unwrap(), Reference::Borrowed(&[1, 2, 3, 4, 5, 6][..])); + assert_eq!(rd.read_slice(6).unwrap(), + Reference::Borrowed(&[1, 2, 3, 4, 5, 6][..])); assert!(rd.read_slice(5).is_err()); - assert_eq!(rd.read_slice(4).unwrap(), Reference::Borrowed(&[7, 8, 9, 10][..])); + assert_eq!(rd.read_slice(4).unwrap(), + Reference::Borrowed(&[7, 8, 9, 10][..])); } /// Deserialize an instance of type `T` from an I/O stream of MessagePack. @@ -606,3 +612,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 545e6c75..500584b6 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -92,6 +92,33 @@ 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 +155,10 @@ impl Serializer { pub fn new(wr: W) -> Self { Serializer::with(wr, StructArrayWriter) } + pub fn compact(wr: W) -> Self { + Serializer::with(wr, StructArrayWriter) + } + } impl Serializer { @@ -238,9 +269,10 @@ impl<'a, W: Write + 'a, V: VariantWriter + 'a> SerializeStruct for Compound<'a, type Ok = (); type Error = Error; - fn serialize_field(&mut self, key: &'static str, value: &T) -> - Result<(), Self::Error> - { + fn serialize_field(&mut self, + key: &'static str, + value: &T) + -> Result<(), Self::Error> { self.se.vw.write_field_name(&mut self.se.wr, key)?; value.serialize(&mut *self.se) } @@ -254,9 +286,10 @@ impl<'a, W: Write + 'a, V: VariantWriter + 'a> SerializeStructVariant for Compou type Ok = (); type Error = Error; - fn serialize_field(&mut self, _key: &'static str, value: &T) -> - Result<(), Self::Error> - { + fn serialize_field(&mut self, + _key: &'static str, + value: &T) + -> Result<(), Self::Error> { value.serialize(&mut *self.se) } @@ -363,21 +396,31 @@ impl<'a, W: Write, V: VariantWriter> serde::Serializer for &'a mut Serializer - Result - { + fn serialize_unit_variant(self, + _name: &str, + idx: u32, + _variant: &str) + -> Result { write_array_len(&mut self.wr, 2)?; self.serialize_u32(idx)?; write_array_len(&mut self.wr, 0)?; Ok(()) } - fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<(), Self::Error> { + fn serialize_newtype_struct(self, + name: &'static str, + value: &T) + -> Result<(), Self::Error> { self.serialize_tuple_struct(name, 1)?; value.serialize(self) } - fn serialize_newtype_variant(self, name: &'static str, variant_index: u32, variant: &'static str, value: &T) -> Result { + fn serialize_newtype_variant(self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T) + -> Result { self.serialize_tuple_variant(name, variant_index, variant, 1)?; value.serialize(self) } @@ -397,15 +440,19 @@ impl<'a, W: Write, V: VariantWriter> serde::Serializer for &'a mut Serializer - Result - { + fn serialize_tuple_struct(self, + _name: &'static str, + len: usize) + -> Result { self.serialize_tuple(len) } - fn serialize_tuple_variant(self, name: &'static str, idx: u32, _variant: &'static str, len: usize) -> - Result - { + fn serialize_tuple_variant(self, + name: &'static str, + idx: u32, + _variant: &'static str, + len: usize) + -> Result { // We encode variant types as a tuple of id with array of args, like: [id, [args...]]. rmp::encode::write_array_len(&mut self.wr, 2)?; self.serialize_u32(idx)?; @@ -422,16 +469,20 @@ impl<'a, W: Write, V: VariantWriter> serde::Serializer for &'a mut Serializer - Result - { + fn serialize_struct(self, + _name: &'static str, + len: usize) + -> Result { self.vw.write_struct_len(&mut self.wr, len as u32)?; Ok(Compound { se: self }) } - fn serialize_struct_variant(self, name: &'static str, id: u32, _variant: &'static str, len: usize) -> - Result - { + fn serialize_struct_variant(self, + name: &'static str, + id: u32, + _variant: &'static str, + len: usize) + -> Result { write_array_len(&mut self.wr, 2)?; self.serialize_u32(id)?; self.serialize_struct(name, len) @@ -439,6 +490,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::new_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] @@ -461,3 +530,16 @@ 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::new_named(&mut buf))?; + Ok(buf) +} diff --git a/rmp-serde/src/lib.rs b/rmp-serde/src/lib.rs index eea83021..e2a57460 100644 --- a/rmp-serde/src/lib.rs +++ b/rmp-serde/src/lib.rs @@ -269,19 +269,8 @@ 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) -} +// 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}; -/// 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/tests/round.rs b/rmp-serde/tests/round.rs index 76911525..eda0e1b1 100644 --- a/rmp-serde/tests/round.rs +++ b/rmp-serde/tests/round.rs @@ -34,7 +34,7 @@ fn round_trip_cow() { v: Cow<'a, [u8]>, } - let expected = Foo { v : Cow::Borrowed(&[]) }; + let expected = Foo { v: Cow::Borrowed(&[]) }; let mut buf = Vec::new(); expected.serialize(&mut Serializer::new(&mut buf)).unwrap(); @@ -55,7 +55,7 @@ fn round_trip_option_cow() { v: Option>, } - let expected = Foo { v : None }; + let expected = Foo { v: None }; let mut buf = Vec::new(); expected.serialize(&mut Serializer::new(&mut buf)).unwrap(); @@ -86,3 +86,41 @@ 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); + +}