summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSam Scott <sam.scott89@gmail.com>2017-05-21 16:08:51 +0100
committerSam Scott <sam.scott89@gmail.com>2017-05-21 16:08:51 +0100
commit6429b975c6cbcf5d7e0c2b1d02026f8d46b5c50f (patch)
tree4c0fe278c27ad294e0ec363d75d1a4175816f031 /tests
parent58de85c0f7ee67294cc1554be2c77af5eecd651a (diff)
Stop LevelDeserializer from coercing values too early.
When deserializing types such as TupleStructs, if the `Level` value is a map, let's call `visit_map` instead of coercing it to a sequence immediately.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_deserialize.rs71
1 files changed, 71 insertions, 0 deletions
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);
+}