From b26f291d93b269a4c3ba9a6f8b47e1eeccb1d7de Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 16 Jan 2017 16:55:13 +0100 Subject: [PATCH] add missing `Vec` deserialization hint to `Deserializer` --- serde/src/bytes.rs | 2 +- serde/src/de/mod.rs | 13 ++++++++++++- serde/src/de/value.rs | 24 ++++++++++++------------ serde/src/macros.rs | 3 +++ serde_test/src/de.rs | 5 +++++ serde_test/src/token.rs | 1 + testing/tests/test_bytes.rs | 2 ++ 7 files changed, 36 insertions(+), 14 deletions(-) diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs index 574a673d..8402b4bd 100644 --- a/serde/src/bytes.rs +++ b/serde/src/bytes.rs @@ -234,7 +234,7 @@ mod bytebuf { fn deserialize(deserializer: D) -> Result where D: de::Deserializer { - deserializer.deserialize_bytes(ByteBufVisitor) + deserializer.deserialize_byte_buf(ByteBufVisitor) } } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index af488dd4..f6307eab 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -174,6 +174,9 @@ pub enum Type { /// Represents a `&[u8]` type. Bytes, + + /// Represents a `Vec` type. + ByteBuf, } impl fmt::Display for Type { @@ -212,6 +215,7 @@ impl fmt::Display for Type { Type::UnitVariant => "unit variant", Type::NewtypeVariant => "newtype variant", Type::Bytes => "bytes", + Type::ByteBuf => "bytes buf", }; display.fmt(formatter) } @@ -343,12 +347,19 @@ pub trait Deserializer { visitor: V) -> Result where V: Visitor; - /// This method hints that the `Deserialize` type is expecting a `Vec`. This allows + /// This method hints that the `Deserialize` type is expecting a `&[u8]`. This allows /// deserializers that provide a custom byte vector serialization to properly deserialize the /// type. fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor; + /// This method hints that the `Deserialize` type is expecting a `Vec`. This allows + /// deserializers that provide a custom byte vector serialization to properly deserialize the + /// type and prevent needless intermediate allocations that would occur when going through + /// `&[u8]`. + fn deserialize_byte_buf(self, visitor: V) -> Result + where V: Visitor; + /// This method hints that the `Deserialize` type is expecting a map of values. This allows /// deserializers to parse sequences that aren't tagged as maps. fn deserialize_map(self, visitor: V) -> Result diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 52342cec..c6472474 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -181,7 +181,7 @@ impl de::Deserializer for UnitDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -223,7 +223,7 @@ macro_rules! primitive_deserializer { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct struct_field tuple enum - ignored_any + ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -288,7 +288,7 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E> forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple ignored_any + tuple_struct struct struct_field tuple ignored_any byte_buf } } @@ -346,7 +346,7 @@ impl de::Deserializer for StringDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple ignored_any + tuple_struct struct struct_field tuple ignored_any byte_buf } } @@ -408,7 +408,7 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E> forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple ignored_any + tuple_struct struct struct_field tuple ignored_any byte_buf } } @@ -469,7 +469,7 @@ impl de::Deserializer for SeqDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } } @@ -572,7 +572,7 @@ impl de::Deserializer for SeqVisitorDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } } @@ -675,7 +675,7 @@ impl de::Deserializer for MapDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option bytes map unit_struct newtype_struct tuple_struct struct - struct_field tuple enum ignored_any + struct_field tuple enum ignored_any byte_buf } } @@ -772,7 +772,7 @@ impl de::Deserializer for PairDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option bytes map unit_struct newtype_struct tuple_struct struct - struct_field tuple enum ignored_any + struct_field tuple enum ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -901,7 +901,7 @@ impl de::Deserializer for MapVisitorDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } } @@ -934,7 +934,7 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E> forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } } @@ -970,7 +970,7 @@ impl de::Deserializer for ByteBufDeserializer forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct struct_field tuple enum ignored_any byte_buf } } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 2580980f..44718108 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -92,6 +92,9 @@ macro_rules! forward_to_deserialize_helper { (bytes) => { forward_to_deserialize_method!{deserialize_bytes()} }; + (byte_buf) => { + forward_to_deserialize_method!{deserialize_byte_buf()} + }; (map) => { forward_to_deserialize_method!{deserialize_map()} }; diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 80ba9e80..849bdf27 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -160,6 +160,10 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer where __V: de::Visitor { self.deserialize(visitor) } + fn deserialize_byte_buf<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error> + where __V: de::Visitor { + self.deserialize(visitor) + } fn deserialize_ignored_any<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error> where __V: de::Visitor { self.deserialize(visitor) @@ -250,6 +254,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer Some(Token::Str(v)) => visitor.visit_str(v), Some(Token::String(v)) => visitor.visit_string(v), Some(Token::Bytes(v)) => visitor.visit_bytes(v), + Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v), Some(Token::Option(false)) => visitor.visit_none(), Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Unit) => visitor.visit_unit(), diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index e4b3a825..b8bd23c6 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -17,6 +17,7 @@ pub enum Token<'a> { Str(&'a str), String(String), Bytes(&'a [u8]), + ByteBuf(Vec), Option(bool), diff --git a/testing/tests/test_bytes.rs b/testing/tests/test_bytes.rs index 6968f900..86067627 100644 --- a/testing/tests/test_bytes.rs +++ b/testing/tests/test_bytes.rs @@ -15,6 +15,7 @@ fn test_bytes() { fn test_byte_buf() { let empty = ByteBuf::new(); assert_tokens(&empty, &[Token::Bytes(b"")]); + assert_de_tokens(&empty, &[Token::ByteBuf(Vec::new())]); assert_de_tokens(&empty, &[Token::Str("")]); assert_de_tokens(&empty, &[Token::String(String::new())]); assert_de_tokens(&empty, &[ @@ -28,6 +29,7 @@ fn test_byte_buf() { let buf = ByteBuf::from(vec![65, 66, 67]); assert_tokens(&buf, &[Token::Bytes(b"ABC")]); + assert_de_tokens(&buf, &[Token::ByteBuf(vec![65, 66, 67])]); assert_de_tokens(&buf, &[Token::Str("ABC")]); assert_de_tokens(&buf, &[Token::String("ABC".to_owned())]); assert_de_tokens(&buf, &[