From f7fa028b78e0af606cec6f699aa6bfbb3450cc39 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 25 Apr 2017 10:00:17 -0500 Subject: add a couple failing tests --- src/de.rs | 5 +++-- tests/test_deserialize.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/de.rs b/src/de.rs index f0b8614..01ae495 100644 --- a/src/de.rs +++ b/src/de.rs @@ -541,7 +541,6 @@ impl<'de> de::MapAccess<'de> for Deserializer { fn next_key_seed(&mut self, seed: K) -> Result, Error> where K: de::DeserializeSeed<'de>, { - if let Some((key, value)) = self.iter.next() { self.value = Some(value); return seed.deserialize(key.into_deserializer()).map(Some); @@ -579,7 +578,9 @@ macro_rules! deserialize_primitive { stringify!($ty)))) }, Level::Flat(x) => { - visitor.$visit_method(str::FromStr::from_str(&x).unwrap()) + let val = str::FromStr::from_str(&x) + .map_err(|e| de::Error::custom(e))?; + visitor.$visit_method(val) }, Level::Invalid(e) => { Err(de::Error::custom(e)) diff --git a/tests/test_deserialize.rs b/tests/test_deserialize.rs index cd22458..4d44e5e 100644 --- a/tests/test_deserialize.rs +++ b/tests/test_deserialize.rs @@ -174,6 +174,34 @@ fn qs_test_simple() { // }); } +#[test] +fn qs_u32_map() { + #[derive(Debug,Serialize,Deserialize,PartialEq)] + struct Query { + map: HashMap + } + + let query = { + let mut map = HashMap::new(); + map.insert(10, "Hello".into()); + Query { map: map } + }; + + let params: Query = qs::from_str("map[10]=Hello").unwrap(); + assert_eq!(params, query) +} + +#[test] +fn no_panic_on_parse_error() { + #[derive(Debug,Serialize,Deserialize,PartialEq)] + struct Query { + vec: Vec + } + + let params: Result = qs::from_str("vec[]=a&vec[]=2"); + assert!(params.is_err()) +} + #[test] fn qs_nesting() { // t.deepEqual(qs.parse('a[b]=c'), { a: { b: 'c' } }, 'parses a single -- cgit v1.2.3 From 50ee9133881bd5d8189c4396bd6eb3e360a5b19e Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 25 Apr 2017 10:49:41 -0500 Subject: add string wrapper --- src/de.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/src/de.rs b/src/de.rs index 01ae495..def50ec 100644 --- a/src/de.rs +++ b/src/de.rs @@ -490,7 +490,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { -> Result where V: de::Visitor<'de>, { - visitor.visit_map(self) + self.deserialize_map(visitor) } fn deserialize_seq(self, visitor: V) -> Result @@ -543,7 +543,7 @@ impl<'de> de::MapAccess<'de> for Deserializer { { if let Some((key, value)) = self.iter.next() { self.value = Some(value); - return seed.deserialize(key.into_deserializer()).map(Some); + return seed.deserialize(ParsableStringDeserializer(key)).map(Some); }; Ok(None) @@ -578,9 +578,7 @@ macro_rules! deserialize_primitive { stringify!($ty)))) }, Level::Flat(x) => { - let val = str::FromStr::from_str(&x) - .map_err(|e| de::Error::custom(e))?; - visitor.$visit_method(val) + ParsableStringDeserializer(x).$method(visitor) }, Level::Invalid(e) => { Err(de::Error::custom(e)) @@ -704,3 +702,75 @@ impl<'de> IntoDeserializer<'de> for Level { LevelDeserializer(self) } } + +macro_rules! forward_parsable_to_deserialize_any { + ($($ty:ident => $meth:ident,)*) => { + $( + fn $meth(self, visitor: V) -> Result where V: de::Visitor<'de> { + match self.0.parse::<$ty>() { + Ok(val) => val.into_deserializer().$meth(visitor), + Err(e) => Err(de::Error::custom(e)) + } + } + )* + } +} + + +pub struct ParsableStringDeserializer(String); + +impl<'de> de::Deserializer<'de> for ParsableStringDeserializer { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where V: de::Visitor<'de>, + { + self.0.into_deserializer().deserialize_any(visitor) + } + + forward_to_deserialize_any! { + // bool + // u8 + // u16 + // u32 + // u64 + // i8 + // i16 + // i32 + // i64 + // f32 + // f64 + map + struct + seq + option + char + str + string + unit + bytes + byte_buf + unit_struct + newtype_struct + tuple_struct + identifier + tuple + enum + ignored_any + } + + forward_parsable_to_deserialize_any! { + bool => deserialize_bool, + u8 => deserialize_u8, + u16 => deserialize_u16, + u32 => deserialize_u32, + u64 => deserialize_u64, + i8 => deserialize_i8, + i16 => deserialize_i16, + i32 => deserialize_i32, + i64 => deserialize_i64, + f32 => deserialize_f32, + f64 => deserialize_f64, + } + +} -- cgit v1.2.3