summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--src/de/mod.rs51
-rw-r--r--tests/test_deserialize.rs71
3 files changed, 115 insertions, 8 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e4f3af7..da6c987 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,7 @@ url = "1.0.0"
[dev-dependencies]
csv = "0.15"
rand = "0.3"
+serde_json = "1.0.2"
serde_urlencoded = "0.4"
[lib]
diff --git a/src/de/mod.rs b/src/de/mod.rs
index 03e4065..cf2768b 100644
--- a/src/de/mod.rs
+++ b/src/de/mod.rs
@@ -505,10 +505,9 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
},
Level::Sequence(_) => {
self.deserialize_seq(visitor)
-
},
Level::Flat(x) => {
- visitor.visit_string(x)
+ ParsableStringDeserializer(x).deserialize_any(visitor)
},
Level::Invalid(e) => {
Err(de::Error::custom(e))
@@ -593,7 +592,20 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
) -> Result<V::Value>
where V: de::Visitor<'de>
{
- self.deserialize_seq(visitor)
+ match self.0 {
+ Level::Nested(_) => {
+ self.deserialize_map(visitor)
+ },
+ Level::Sequence(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Flat(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Invalid(e) => {
+ Err(de::Error::custom(e))
+ }
+ }
}
fn deserialize_tuple<V>(
@@ -603,8 +615,20 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
) -> Result<V::Value>
where V: de::Visitor<'de>
{
- self.deserialize_seq(visitor)
-
+ match self.0 {
+ Level::Nested(_) => {
+ self.deserialize_map(visitor)
+ },
+ Level::Sequence(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Flat(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Invalid(e) => {
+ Err(de::Error::custom(e))
+ }
+ }
}
fn deserialize_tuple_struct<V>(
self,
@@ -614,8 +638,20 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
) -> Result<V::Value>
where V: de::Visitor<'de>
{
- self.deserialize_seq(visitor)
- }
+ match self.0 {
+ Level::Nested(_) => {
+ self.deserialize_map(visitor)
+ },
+ Level::Sequence(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Flat(_) => {
+ self.deserialize_seq(visitor)
+ },
+ Level::Invalid(e) => {
+ Err(de::Error::custom(e))
+ }
+ } }
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where V: de::Visitor<'de>
@@ -705,7 +741,6 @@ impl<'de> de::Deserializer<'de> for ParsableStringDeserializer {
self.0.into_deserializer().deserialize_any(visitor)
}
-
forward_to_deserialize_any! {
map
struct
diff --git a/tests/test_deserialize.rs b/tests/test_deserialize.rs
index 3e0c843..79d1589 100644
--- a/tests/test_deserialize.rs
+++ b/tests/test_deserialize.rs
@@ -1,7 +1,11 @@
+extern crate serde;
#[macro_use]
extern crate serde_derive;
+#[macro_use]
+extern crate serde_json as json;
extern crate serde_qs as qs;
+use std::fmt;
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@@ -376,3 +380,70 @@ fn deserialize_enum() {
let rec_params: E = qs::from_str(params).unwrap();
assert_eq!(rec_params, E::S("Hello World".to_string()));
}
+
+
+#[test]
+fn deserialize_custom() {
+ use serde::de::{self, Deserialize, Visitor, Deserializer};
+
+ #[derive(Deserialize, Debug, Clone, Copy, PartialEq, Serialize)]
+ #[serde(rename_all = "lowercase")]
+ enum TestEnum { Foo, Bar }
+
+ #[derive(Deserialize, Debug, Serialize, PartialEq)]
+ struct TestStruct {
+ e: TestEnum,
+ }
+
+ #[derive(Deserialize, Debug, PartialEq)]
+ struct NestedStruct {
+ ts: Vec<TupleStruct>,
+ }
+
+ #[derive(Debug, PartialEq)]
+ struct TupleStruct(TestEnum, TestStruct);
+
+ impl<'de> serde::de::Deserialize<'de> for TupleStruct {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where D: Deserializer<'de>
+ {
+ deserializer.deserialize_tuple_struct(
+ "TupleStruct", 2, TupleStructVisitor)
+ }
+ }
+
+ struct TupleStructVisitor;
+ impl<'de> Visitor<'de> for TupleStructVisitor {
+ type Value = TupleStruct;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(fmt, "TupleStruct representation")
+ }
+
+ fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
+ where V: de::MapAccess<'de>
+ {
+ let inner_de = de::value::MapAccessDeserializer::new(map);
+ let test_struct: TestStruct = Deserialize::deserialize(inner_de)?;
+
+ let result = TupleStruct(test_struct.e, test_struct);
+ Ok(result)
+ }
+ }
+
+
+ let expected = NestedStruct {
+ ts: vec![TupleStruct(TestEnum::Bar, TestStruct { e: TestEnum::Bar}), TupleStruct(TestEnum::Foo, TestStruct { e: TestEnum::Foo})],
+ };
+
+ let json_struct: NestedStruct = json::from_str(&json!({
+ "ts": [{"e": "bar"}, {"e": "foo"}],
+ }).to_string()).unwrap();
+
+ let qs_struct: NestedStruct = qs::from_str(
+ "ts[0][e]=bar&ts[1][e]=foo"
+ ).unwrap();
+
+ assert_eq!(qs_struct, json_struct);
+ assert_eq!(qs_struct, expected);
+}