From 6d25fc9dbbeb97d560b53bae0e2787eb0219e06b Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Thu, 28 Jan 2016 08:38:07 -0800 Subject: [PATCH 1/2] feat(de): Support struct key hinting Formats that do not provide type hints in the serialized format (bincode, redis) rely on hinting in the deserializer. Struct key hinting was not previously supported. This was not an issue in the past because bincode serializes structs as a keyless sequence of values. However, redis data is stored (key, value, key, value, ...), and the keys must be deserialized to properly create a struct. The default implementation of `visit_struct_key` is simply `visit` since that was the previous method called in codegen. --- serde/src/de/mod.rs | 10 ++++++++++ serde_codegen/src/de.rs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 75c3f4b0..637bab6d 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -403,6 +403,16 @@ pub trait Deserializer { self.visit_seq(visitor) } + /// This method hints that the `Deserialize` type is expecting some sort of struct key mapping. + /// This allows deserializers to choose between &str, usize, or &[u8] to properly deserialize a + /// struct key. + #[inline] + fn visit_struct_key(&mut self, visitor: V) -> Result + where V: Visitor, + { + self.visit(visitor) + } + /// Specify a format string for the deserializer. /// /// The deserializer format is used to determine which format diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index 6980507b..a327993c 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -917,7 +917,7 @@ fn deserialize_field_visitor( } } - deserializer.visit(__FieldVisitor::{ phantom: PhantomData }) + deserializer.visit_struct_key(__FieldVisitor::{ phantom: PhantomData }) } } ).unwrap(); From 4507eaec5b0d136d65ac823424e007c3d79a36bf Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 28 Jan 2016 09:45:38 -0800 Subject: [PATCH 2/2] Use deserializer.visit_string for PathBuf --- serde/src/de/impls.rs | 2 +- serde_tests/tests/test_de.rs | 6 ++++++ serde_tests/tests/test_ser.rs | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index ef696484..2a8fc00f 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -762,7 +762,7 @@ impl Deserialize for path::PathBuf { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { - deserializer.visit(PathBufVisitor) + deserializer.visit_string(PathBufVisitor) } } diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index f818b105..7663619e 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::path::PathBuf; use num::FromPrimitive; use num::bigint::{BigInt, BigUint}; @@ -589,4 +590,9 @@ declare_tests! { Token::SeqEnd, ], } + test_path_buf { + PathBuf::from("/usr/local/lib") => vec![ + Token::String("/usr/local/lib".to_owned()), + ], + } } diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index a5947508..7fbae4e4 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; use num::FromPrimitive; use num::bigint::{BigInt, BigUint}; @@ -293,4 +294,14 @@ declare_ser_tests! { Token::SeqEnd, ], } + test_path { + Path::new("/usr/local/lib") => &[ + Token::Str("/usr/local/lib"), + ], + } + test_path_buf { + PathBuf::from("/usr/local/lib") => &[ + Token::Str("/usr/local/lib"), + ], + } }