diff options
author | Sam Scott <sam.scott89@gmail.com> | 2017-05-20 22:57:58 +0100 |
---|---|---|
committer | Sam Scott <sam.scott89@gmail.com> | 2017-05-20 22:57:58 +0100 |
commit | 661cc9697a1c31abe786e45e43072800b6641871 (patch) | |
tree | 9d7d20656320d4bf5fb437d8f8d13b0e41131571 /src | |
parent | 6e71ba43eb6bd62f2b567224e387333016bd3a5c (diff) |
Organisational changes.
Diffstat (limited to 'src')
-rw-r--r-- | src/de.rs | 975 | ||||
-rw-r--r-- | src/de/mod.rs | 652 | ||||
-rw-r--r-- | src/de/parse.rs | 359 | ||||
-rw-r--r-- | src/lib.rs | 2 |
4 files changed, 1013 insertions, 975 deletions
diff --git a/src/de.rs b/src/de.rs deleted file mode 100644 index 0306d21..0000000 --- a/src/de.rs +++ /dev/null @@ -1,975 +0,0 @@ -//! Deserialization support for querystrings. - -use data_encoding::base64; - -use serde::de; -#[doc(inline)] -pub use serde::de::value::Error; -use serde::de::value::MapDeserializer; -use url::percent_encoding; - -use std::collections::btree_map::{BTreeMap, Entry, IntoIter}; -use std::io::Read; -use std::vec; -/// To override the default serialization parameters, first construct a new -/// Config. -/// -/// A `max_depth` of 0 implies no nesting: the result will be a flat map. -/// This is mostly useful when the maximum nested depth is known beforehand, -/// to prevent denial of service attacks by providing incredibly deeply nested -/// inputs. -/// -/// ``` -/// use serde_qs::de::Config; -/// use std::collections::HashMap; -/// -/// let mut config = Config::default(); -/// config.max_depth(0); -/// let map: HashMap<String, String> = config.deserialize_str("a[b][c]=1") -/// .unwrap(); -/// assert_eq!(map.get("a[b][c]").unwrap(), "1"); -/// -/// config.max_depth(10); -/// let map: HashMap<String, HashMap<String, HashMap<String, String>>> = -/// config.deserialize_str("a[b][c]=1").unwrap(); -/// assert_eq!(map.get("a").unwrap().get("b").unwrap().get("c").unwrap(), "1"); -/// ``` -/// -pub struct Config { - /// Specifies the maximum depth key that `serde_qs` will attempt to - /// deserialize. Default is 5. - max_depth: usize, -} - -impl Default for Config { - fn default() -> Self { - Config { max_depth: 5 } - } -} - -impl Config { - pub fn max_depth(&mut self, depth: usize) { - self.max_depth = depth; - } -} - -impl Config { - pub fn deserialize_bytes<'de, T: de::Deserialize<'de>>(&self, - input: &[u8]) - -> Result<T, Error> { - T::deserialize(Deserializer::with_config(self, input)) - } - - pub fn deserialize_str<'de, T: de::Deserialize<'de>>(&self, - input: &str) - -> Result<T, Error> { - self.deserialize_bytes(input.as_bytes()) - } - - pub fn deserialize_reader<'de, T, R>(&self, mut reader: R) -> Result<T, Error> - where T: de::Deserialize<'de>, - R: Read, - { - let mut buf = vec![]; - reader.read_to_end(&mut buf) - .map_err(|e| { - de::Error::custom(format_args!("could not read input: {}", e)) - })?; - self.deserialize_bytes(&buf) - // from_bytes(&buf) - // T::deserialize(Deserializer::with_config(self, input.as_bytes())) - } -} -/// Deserializes a querystring from a `&[u8]`. -/// -/// ``` -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde_qs; -/// #[derive(Debug, Deserialize, PartialEq, Serialize)] -/// struct Query { -/// name: String, -/// age: u8, -/// occupation: String, -/// } -/// -/// # fn main(){ -/// let q = Query { -/// name: "Alice".to_owned(), -/// age: 24, -/// occupation: "Student".to_owned(), -/// }; -/// -/// assert_eq!( -/// serde_qs::from_bytes::<Query>( -/// "name=Alice&age=24&occupation=Student".as_bytes() -/// ), -/// Ok(q)); -/// # } -/// ``` -pub fn from_bytes<'de, T: de::Deserialize<'de>>(input: &[u8]) -> Result<T, Error> { - Config::default().deserialize_bytes(input) -} - -/// Deserializes a querystring from a `&str`. -/// -/// ``` -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde_qs; -/// #[derive(Debug, Deserialize, PartialEq, Serialize)] -/// struct Query { -/// name: String, -/// age: u8, -/// occupation: String, -/// } -/// -/// # fn main(){ -/// let q = Query { -/// name: "Alice".to_owned(), -/// age: 24, -/// occupation: "Student".to_owned(), -/// }; -/// -/// assert_eq!( -/// serde_qs::from_str::<Query>("name=Alice&age=24&occupation=Student"), -/// Ok(q)); -/// # } -/// ``` -pub fn from_str<'de, T: de::Deserialize<'de>>(input: &str) -> Result<T, Error> { - from_bytes(input.as_bytes()) -} - -/// Convenience function that reads all bytes from `reader` and deserializes -/// them with `from_bytes`. -pub fn from_reader<'de, T, R>(mut reader: R) -> Result<T, Error> - where T: de::Deserialize<'de>, - R: Read, -{ - let mut buf = vec![]; - reader.read_to_end(&mut buf) - .map_err(|e| { - de::Error::custom(format_args!("could not read input: {}", e)) - })?; - from_bytes(&buf) -} - -/// A deserializer for the querystring format. -/// -/// Supported top-level outputs are structs and maps. -pub struct Deserializer { - iter: IntoIter<String, Level>, - value: Option<Level>, -} - -#[derive(Debug)] -enum Level { - Nested(BTreeMap<String, Level>), - Sequence(Vec<Level>), - Flat(String), - Invalid(&'static str), -} - -macro_rules! tu { - ($x:expr) => ( - match $x { - Some(x) => x, - None => return Err( - de::Error::custom("query string ended before expected")) - } - ) -} - -use std::iter::Iterator; -use std::str; - -struct Parser<I: Iterator<Item = u8>> { - inner: I, - acc: Vec<u8>, - peeked: Option<u8>, - depth: usize, -} - -impl<I: Iterator<Item = u8>> Iterator for Parser<I> { - type Item = u8; - #[inline] - fn next(&mut self) -> Option<Self::Item> { - self.inner.next() - } -} - - -fn insert_into_map(node: &mut Level, key: String, value: String) { - if let Level::Nested(ref mut map) = *node { - match map.entry(key) { - Entry::Occupied(mut o) => { - o.insert(Level::Invalid("Multiple values for one key")); - }, - Entry::Vacant(vm) => { - vm.insert(Level::Flat(value)); - }, - } - } else { - let mut map = BTreeMap::default(); - map.insert(key, Level::Flat(value)); - *node = Level::Nested(map); - } -} - -impl<I: Iterator<Item = u8>> Parser<I> { - #[inline] - fn peek(&mut self) -> Option<<Self as Iterator>::Item> { - if !self.acc.is_empty() { - self.peeked - } else if let Some(x) = self.inner.next() { - self.acc.push(x); - self.peeked = Some(x); - Some(x) - } else { - None - } - } - - fn parse_key(&mut self, - end_on: u8, - consume: bool) - -> Result<String, Error> { - loop { - if let Some(x) = self.next() { - match x { - x if x == end_on => { - let res = String::from_utf8(self.acc.split_off(0)); - self.acc.clear(); - - // Add this character back to the buffer for peek. - if !consume { - self.acc.push(x); - self.peeked = Some(x); - } - return res.map_err(|_| de::Error::custom("blah")); - }, - b'=' => { - // Allow the '=' byte when parsing keys within [] - if end_on == b']' { - self.acc.push(b'='); - } else { - let res = String::from_utf8(self.acc.split_off(0)); - self.acc.clear(); - - // Add this character back to the buffer for peek. - self.acc.push(b'='); - self.peeked = Some(b'='); - - return res.map_err(|_| de::Error::custom("blah")); - } - }, - b' ' => { - self.acc.push(b' '); - }, - b'&' => { - let res = String::from_utf8(self.acc.split_off(0)); - self.acc.clear(); - self.acc.push(b'&'); - self.peeked = Some(b'&'); - return res.map_err(|_| de::Error::custom("blah")); - }, - x @ 0x20...0x7e => { - self.acc.push(x); - }, - _ => { - return Err(de::Error::custom("unexpected character \ - in query string.")); - }, - } - } else { - // End of string. - let res = String::from_utf8(self.acc.split_off(0)); - self.acc.clear(); - return res.map_err(|_| de::Error::custom("blah")); - } - } - } - - fn parse_map_value(&mut self, - key: String, - node: &mut Level) - -> Result<(), Error> { - if let Some(x) = self.peek() { - match x { - b'=' => { - self.acc.clear(); - for b in self.inner.by_ref().take_while(|b| b != &b'&') { - if b == b'+' { - self.acc.push(b' '); - } else { - self.acc.push(b); - } - } - let value = String::from_utf8(self.acc.split_off(0)); - let value = value.map_err(|_e| de::Error::custom("blah"))?; - // Reached the end of the key string - insert_into_map(node, key, value); - Ok(()) - }, - b'&' => { - insert_into_map(node, key, "".to_string()); - Ok(()) - }, - b'[' => { - if let Level::Invalid(_) = *node { - *node = Level::Nested(BTreeMap::default()); - } - if let Level::Nested(ref mut map) = *node { - self.depth -= 1; - self.parse(map.entry(key) - .or_insert(Level::Invalid("uninitialised")))?; - Ok(()) - } else { - Err(de::Error::custom(format!("tried to insert a \ - new key into {:?}", - node))) - } - }, - _ => { - panic!("Unexpected character"); - }, - } - } else { - insert_into_map(node, key, "".to_string()); - Ok(()) - } - } - - fn parse_seq_value(&mut self, node: &mut Level) -> Result<(), Error> { - match tu!(self.peek()) { - b'=' => { - self.acc.clear(); - for b in self.inner.by_ref().take_while(|b| b != &b'&') { - self.acc.push(b); - } - let value = String::from_utf8(self.acc.split_off(0)) - .map(|s| s.into()); - let value = - value.map_err(|e| de::Error::custom(e.to_string()))?; - // Reached the end of the key string - if let Level::Sequence(ref mut seq) = *node { - seq.push(Level::Flat(value)); - } else { - let mut seq = Vec::new(); - seq.push(Level::Flat(value)); - *node = Level::Sequence(seq); - } - Ok(()) - }, - _ => { - Err(de::Error::custom("non-indexed sequence of structs not \ - supported")) - }, - } - } - - - fn parse(&mut self, node: &mut Level) -> Result<bool, Error> { - // First character determines parsing type - if self.depth == 0 { - let key = self.parse_key(b'\x00', true)?; - self.parse_map_value(key.into(), node)?; - self.depth += 1; - return Ok(true); - } - match self.peek() { - Some(x) => { - match x { - b'[' => { - self.acc.clear(); - // let _ = self.next(); - match tu!(self.peek()) { - // key is of the form "[...", not really allowed. - b'[' => { - panic!(""); - - }, - // key is simply "[]", so treat as a seq. - b']' => { - self.acc.clear(); - self.parse_seq_value(node)?; - self.depth += 1; - Ok(true) - - }, - // Key is "[a..." so parse up to the closing "]" - 0x20...0x7e => { - let key = self.parse_key(b']', true)?; - self.parse_map_value(key.into(), node)?; - self.depth += 1; - Ok(true) - - }, - _ => { - panic!(""); - }, - } - }, - // This means the key should be a root key - // of the form "abc" or "abc[...]" - 0x20...0x7e => { - let key = self.parse_key(b'[', false)?; - self.parse_map_value(key.into(), node)?; - self.depth += 1; - Ok(true) - }, - _ => { - panic!(""); - }, - } - }, - // Ran out of characters to parse - None => Ok(false), - } - } -} - -impl Deserializer { - fn with_map(map: BTreeMap<String, Level>) -> Self { - Deserializer { - iter: map.into_iter(), - value: None, - } - } - - /// Returns a new `Deserializer`. - fn with_config(config: &Config, input: &[u8]) -> Self { - let map = BTreeMap::default(); - let mut root = Level::Nested(map); - - let decoded = percent_encoding::percent_decode(input); - let mut parser = Parser { - inner: decoded, - acc: Vec::new(), - peeked: None, - depth: config.max_depth, - }; - - while let Ok(x) = parser.parse(&mut root) { - if !x { - break; - } - } - let iter = match root { - Level::Nested(map) => map.into_iter(), - _ => panic!(""), - }; - Deserializer { - iter: iter, - value: None, - } - } -} - -impl<'de> de::Deserializer<'de> for Deserializer { - type Error = Error; - - fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - self.deserialize_map(visitor) - } - - fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - visitor.visit_map(self) - } - - fn deserialize_struct<V>(self, - _name: &'static str, - _fields: &'static [&'static str], - visitor: V) - -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - self.deserialize_map(visitor) - } - - fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - visitor.visit_seq(MapDeserializer::new(self.iter)) - } - - fn deserialize_newtype_struct<V>( - self, - _name: &'static str, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - self.deserialize_map(visitor) - } - - fn deserialize_tuple<V>( - self, - _len: usize, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - visitor.visit_seq(MapDeserializer::new(self.iter)) - - } - fn deserialize_tuple_struct<V>( - self, - _name: &'static str, - _len: usize, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - visitor.visit_seq(MapDeserializer::new(self.iter)) - } - - fn deserialize_enum<V>( - self, - _name: &'static str, - _variants: &'static [&'static str], - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - visitor.visit_enum(self) - } - - forward_to_deserialize_any! { - bool - u8 - u16 - u32 - u64 - i8 - i16 - i32 - i64 - f32 - f64 - char - str - string - unit - option - bytes - byte_buf - unit_struct - // seq - // seq_fixed_size - // newtype_struct - // tuple_struct - // struct - identifier - // struct_field - // tuple - // enum - ignored_any - } -} - -use serde::de::IntoDeserializer; -use serde::de::value::SeqDeserializer; - -impl<'de> de::MapAccess<'de> for Deserializer { - type Error = Error; - - - fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> - where K: de::DeserializeSeed<'de>, - { - if let Some((key, value)) = self.iter.next() { - self.value = Some(value); - return seed.deserialize(ParsableStringDeserializer(key)).map(Some); - }; - Ok(None) - } - - fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> - where V: de::DeserializeSeed<'de>, - { - if let Some(v) = self.value.take() { - seed.deserialize(v.into_deserializer()) - } else { - Err(de::Error::custom("Somehow the list was empty after a \ - non-empty key was returned")) - } - } -} - -impl<'de> de::EnumAccess<'de> for Deserializer { - type Error = Error; - type Variant = LevelDeserializer; - - fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: de::DeserializeSeed<'de> - { - if let Some((key, value)) = self.iter.next() { - Ok((seed.deserialize(ParsableStringDeserializer(key))?, LevelDeserializer(value))) - } else { - Err(de::Error::custom("No more values")) - } - } -} - -impl<'de> de::EnumAccess<'de> for LevelDeserializer { - type Error = Error; - type Variant = Self; - - fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: de::DeserializeSeed<'de> - { - match self.0 { - // Level::Nested(map) => { - // Deserializer::with_map(map).variant_seed(seed) - // }, - // Level::Sequence(_) => { - // Err(de::Error::custom(format!("Expected Enum (map or a flat value), got a Sequence"))) - // }, - Level::Flat(x) => { - Ok((seed.deserialize(ParsableStringDeserializer(x))?, LevelDeserializer(Level::Invalid("")))) - }, - _ => { - Err(de::Error::custom("should not be here...")) - } - } - } -} - -impl<'de> de::VariantAccess<'de> for LevelDeserializer { - type Error = Error; - fn unit_variant(self) -> Result<(), Self::Error> { - Ok(()) - } - - fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> - where - T: de::DeserializeSeed<'de> - { - seed.deserialize(self) - - } - fn tuple_variant<V>( - self, - _len: usize, - visitor: V - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de> - { - de::Deserializer::deserialize_seq(self, visitor) - - } - fn struct_variant<V>( - self, - _fields: &'static [&'static str], - visitor: V - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de> - { - de::Deserializer::deserialize_map(self, visitor) - } -} - -struct LevelSeq<I: Iterator<Item=Level>>(I); - -impl<'de, I: Iterator<Item=Level>> de::SeqAccess<'de> for LevelSeq<I> { - type Error = Error; - fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> - where T: de::DeserializeSeed<'de> - { - if let Some(v) = self.0.next() { - seed.deserialize(v.into_deserializer()).map(Some) - } else { - Ok(None) - } - } -} - - - -pub struct LevelDeserializer(Level); - -macro_rules! deserialize_primitive { - ($ty:ident, $method:ident, $visit_method:ident) => ( - fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - match self.0 { - Level::Nested(_) => { - Err(de::Error::custom(format!("Expected: {:?}, got a Map", - stringify!($ty)))) - }, - Level::Sequence(_) => { - Err(de::Error::custom(format!("Expected: {:?}, got a Sequence", - stringify!($ty)))) - }, - Level::Flat(x) => { - ParsableStringDeserializer(x).$method(visitor) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - } - } - } - ) -} - -impl LevelDeserializer { - fn to_deserializer(self) -> Result<Deserializer, Error> { - match self.0 { - Level::Nested(map) => { - Ok(Deserializer::with_map(map)) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - } - l => { - Err(de::Error::custom(format!("could not convert {:?} to Deserializer", l))) - }, - } - } -} - -impl<'de> de::Deserializer<'de> for LevelDeserializer { - type Error = Error; - - fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - match self.0 { - Level::Nested(map) => { - Deserializer::with_map(map).deserialize_map(visitor) - }, - Level::Sequence(seq) => { - SeqDeserializer::new(seq.into_iter()).deserialize_any(visitor) - }, - Level::Flat(x) => { - visitor.visit_string(x) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - } - } - } - - fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - match self.0 { - Level::Nested(map) => { - visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))) - - // SeqDeserializer::new() - // .deserialize_any(visitor) - }, - Level::Sequence(x) => { - // SeqDeserializer::new(x.into_iter()).deserialize_any(visitor) - visitor.visit_seq(LevelSeq(x.into_iter())) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - }, - x => { - visitor.visit_seq(LevelSeq(vec![x].into_iter())) - }, - } - } - - fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - match self.0 { - Level::Flat(ref x) if x == "" => { - visitor.visit_none() - }, - _ => { - visitor.visit_some(self) - }, - } - } - - fn deserialize_enum<V>( - self, - name: &'static str, - variants: &'static [&'static str], - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - match self.0 { - Level::Nested(map) => { - Deserializer::with_map(map).deserialize_enum(name, variants, visitor) - }, - Level::Flat(_) => { - visitor.visit_enum(self) - }, - _ => { - Err(de::Error::custom("value does not appear to be a sequence")) - }, - } - } - - fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - self.to_deserializer()?.deserialize_map(visitor) - - } - - fn deserialize_struct<V>(self, - name: &'static str, - fields: &'static [&'static str], - visitor: V) - -> Result<V::Value, Self::Error> - where V: de::Visitor<'de>, - { - self.to_deserializer()?.deserialize_struct(name, fields, visitor) - } - - fn deserialize_newtype_struct<V>( - self, - _name: &'static str, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - self.deserialize_seq(visitor) - } - - fn deserialize_tuple<V>( - self, - _len: usize, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - // self.to_deserializer()?.deserialize_tuple(len, visitor) - self.deserialize_seq(visitor) - - } - fn deserialize_tuple_struct<V>( - self, - _name: &'static str, - _len: usize, - visitor: V - ) -> Result<V::Value, Self::Error> - where V: de::Visitor<'de> - { - self.deserialize_seq(visitor) - } - - deserialize_primitive!(bool, deserialize_bool, visit_bool); - deserialize_primitive!(i8, deserialize_i8, visit_i8); - deserialize_primitive!(i16, deserialize_i16, visit_i16); - deserialize_primitive!(i32, deserialize_i32, visit_i32); - deserialize_primitive!(i64, deserialize_i64, visit_i64); - deserialize_primitive!(u8, deserialize_u8, visit_u8); - deserialize_primitive!(u16, deserialize_u16, visit_u16); - deserialize_primitive!(u32, deserialize_u32, visit_u32); - deserialize_primitive!(u64, deserialize_u64, visit_u64); - deserialize_primitive!(f32, deserialize_f32, visit_f32); - deserialize_primitive!(f64, deserialize_f64, visit_f64); - - - forward_to_deserialize_any! { - char - str - string - unit - bytes - byte_buf - unit_struct - // newtype_struct - // tuple_struct - identifier - // tuple - // enum - ignored_any - } -} - -impl<'de> IntoDeserializer<'de> for Level { - type Deserializer = LevelDeserializer; - fn into_deserializer(self) -> Self::Deserializer { - LevelDeserializer(self) - } -} - -macro_rules! forward_parsable_to_deserialize_any { - ($($ty:ident => $meth:ident,)*) => { - $( - fn $meth<V>(self, visitor: V) -> Result<V::Value, Self::Error> 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> - 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, - } - -} diff --git a/src/de/mod.rs b/src/de/mod.rs new file mode 100644 index 0000000..267b4cb --- /dev/null +++ b/src/de/mod.rs @@ -0,0 +1,652 @@ +//! Deserialization support for querystrings. + +mod parse; + +pub use de::parse::Config; + +use data_encoding; +use data_encoding::base64; + +use serde::de; +use serde::de::IntoDeserializer; +use serde::de::value::MapDeserializer; + +use url::percent_encoding; + +use std::collections::btree_map::{BTreeMap, Entry, IntoIter}; +use std::io::{self,Read}; +use std::fmt::Display; +use std::string; + +error_chain! { + errors { Custom(msg: String) } + foreign_links { + Decoding(data_encoding::decode::Error); + Io(io::Error); + Utf8(string::FromUtf8Error); + } +} + +impl Error { + fn top_level(object: &'static str) -> Self { + ErrorKind::Custom(format!("cannot deserialize {} at the top level.\ + Try deserializing into a struct.", object)).into() + + } +} + +impl de::Error for Error { + fn custom<T>(msg: T) -> Self + where T: Display { + ErrorKind::Custom(msg.to_string()).into() + } +} + +/// Deserializes a querystring from a `&[u8]`. +/// +/// ``` +/// # #[macro_use] +/// # extern crate serde_derive; +/// # extern crate serde_qs; +/// #[derive(Debug, Deserialize, PartialEq, Serialize)] +/// struct Query { +/// name: String, +/// age: u8, +/// occupation: String, +/// } +/// +/// # fn main(){ +/// let q = Query { +/// name: "Alice".to_owned(), +/// age: 24, +/// occupation: "Student".to_owned(), +/// }; +/// +/// assert_eq!( +/// serde_qs::from_bytes::<Query>( +/// "name=Alice&age=24&occupation=Student".as_bytes() +/// ).unwrap(), q); +/// # } +/// ``` +pub fn from_bytes<'de, T: de::Deserialize<'de>>(input: &[u8]) -> Result<T> { + Config::default().deserialize_bytes(input) +} + +/// Deserializes a querystring from a `&str`. +/// +/// ``` +/// # #[macro_use] +/// # extern crate serde_derive; +/// # extern crate serde_qs; +/// #[derive(Debug, Deserialize, PartialEq, Serialize)] +/// struct Query { +/// name: String, +/// age: u8, +/// occupation: String, +/// } +/// +/// # fn main(){ +/// let q = Query { +/// name: "Alice".to_owned(), +/// age: 24, +/// occupation: "Student".to_owned(), +/// }; +/// +/// assert_eq!( +/// serde_qs::from_str::<Query>("name=Alice&age=24&occupation=Student").unwrap(), +/// q); +/// # } +/// ``` +pub fn from_str<'de, T: de::Deserialize<'de>>(input: &str) -> Result<T> { + from_bytes(input.as_bytes()) +} + +/// Convenience function that reads all bytes from `reader` and deserializes +/// them with `from_bytes`. +pub fn from_reader<'de, T, R>(mut reader: R) -> Result<T> + where T: de::Deserialize<'de>, + R: Read, +{ + let mut buf = vec![]; + reader.read_to_end(&mut buf) + .map_err(|e| { + ErrorKind::Io(e) + })?; + from_bytes(&buf) +} + +/// A deserializer for the querystring format. +/// +/// Supported top-level outputs are structs and maps. +pub struct Deserializer { + iter: IntoIter<String, Level>, + value: Option<Level>, +} + +#[derive(Debug)] +pub enum Level { + Nested(BTreeMap<String, Level>), + Sequence(Vec<Level>), + Flat(String), + Invalid(&'static str), +} + +impl Deserializer { + fn with_map(map: BTreeMap<String, Level>) -> Self { + Deserializer { + iter: map.into_iter(), + value: None, + } + } + + /// Returns a new `Deserializer`. + fn with_config(config: &Config, input: &[u8]) -> Self { + let decoded = percent_encoding::percent_decode(input); + parse::Parser::new(decoded, vec![], None, config.max_depth()).to_deserializer() + + } +} + +impl<'de> de::Deserializer<'de> for Deserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + self.deserialize_map(visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + visitor.visit_map(self) + } + + fn deserialize_struct<V>(self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V) + -> Result<V::Value> + where V: de::Visitor<'de>, + { + self.deserialize_map(visitor) + } + + /// Throws an error. + /// + /// Sequences are not supported at the top level. + fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + Err(Error::top_level("sequence")) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + self.deserialize_map(visitor) + } + + /// Throws an error. + /// + /// Tuples are not supported at the top level. + fn deserialize_tuple<V>( + self, + _len: usize, + _visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + Err(Error::top_level("tuple")) + + } + + /// Throws an error. + /// + /// TupleStructs are not supported at the top level. + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + _visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + Err(Error::top_level("tuple struct")) + } + + fn deserialize_enum<V>( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool + u8 + u16 + u32 + u64 + i8 + i16 + i32 + i64 + f32 + f64 + char + str + string + unit + option + bytes + byte_buf + unit_struct + // seq + // seq_fixed_size + // newtype_struct + // tuple_struct + // struct + identifier + // struct_field + // tuple + // enum + ignored_any + } +} + +// use serde::de::IntoDeserializer; +// use serde::de::value::SeqDeserializer; + +impl<'de> de::MapAccess<'de> for Deserializer { + type Error = Error; + + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>> + where K: de::DeserializeSeed<'de>, + { + if let Some((key, value)) = self.iter.next() { + self.value = Some(value); + return seed.deserialize(ParsableStringDeserializer(key)).map(Some); + }; + Ok(None) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> + where V: de::DeserializeSeed<'de>, + { + if let Some(v) = self.value.take() { + seed.deserialize(LevelDeserializer(v)) + } else { + Err(de::Error::custom("Somehow the list was empty after a \ + non-empty key was returned")) + } + } +} + +impl<'de> de::EnumAccess<'de> for Deserializer { + type Error = Error; + type Variant = LevelDeserializer; + + fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant)> + where V: de::DeserializeSeed<'de> + { + if let Some((key, value)) = self.iter.next() { + Ok((seed.deserialize(ParsableStringDeserializer(key))?, LevelDeserializer(value))) + } else { + Err(de::Error::custom("No more values")) + } + } +} + +impl<'de> de::EnumAccess<'de> for LevelDeserializer { + type Error = Error; + type Variant = Self; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)> + where V: de::DeserializeSeed<'de> + { + match self.0 { + Level::Flat(x) => { + Ok((seed.deserialize(ParsableStringDeserializer(x))?, LevelDeserializer(Level::Invalid("")))) + }, + _ => { + Err(de::Error::custom("should not be here...")) + } + } + } +} + +impl<'de> de::VariantAccess<'de> for LevelDeserializer { + type Error = Error; + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> + where + T: de::DeserializeSeed<'de> + { + seed.deserialize(self) + + } + fn tuple_variant<V>( + self, + _len: usize, + visitor: V + ) -> Result<V::Value> + where + V: de::Visitor<'de> + { + de::Deserializer::deserialize_seq(self, visitor) + + } + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + visitor: V + ) -> Result<V::Value> + where + V: de::Visitor<'de> + { + de::Deserializer::deserialize_map(self, visitor) + } +} + +struct LevelSeq<I: Iterator<Item=Level>>(I); + +impl<'de, I: Iterator<Item=Level>> de::SeqAccess<'de> for LevelSeq<I> { + type Error = Error; + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> + where T: de::DeserializeSeed<'de> + { + if let Some(v) = self.0.next() { + seed.deserialize(LevelDeserializer(v)).map(Some) + } else { + Ok(None) + } + } +} + + + +pub struct LevelDeserializer(Level); + +macro_rules! deserialize_primitive { + ($ty:ident, $method:ident, $visit_method:ident) => ( + fn $method<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + match self.0 { + Level::Nested(_) => { + Err(de::Error::custom(format!("Expected: {:?}, got a Map", + stringify!($ty)))) + }, + Level::Sequence(_) => { + Err(de::Error::custom(format!("Expected: {:?}, got a Sequence", + stringify!($ty)))) + }, + Level::Flat(x) => { + ParsableStringDeserializer(x).$method(visitor) + }, + Level::Invalid(e) => { + Err(de::Error::custom(e)) + } + } + } + ) +} + +impl LevelDeserializer { + fn to_deserializer(self) -> Result<Deserializer> { + match self.0 { + Level::Nested(map) => { + Ok(Deserializer::with_map(map)) + }, + Level::Invalid(e) => { + Err(de::Error::custom(e)) + } + l => { + Err(de::Error::custom(format!("could not convert {:?} to Deserializer", l))) + }, + } + } +} + +impl<'de> de::Deserializer<'de> for LevelDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + match self.0 { + Level::Nested(_) => { + // Deserializer::with_map(map).deserialize_map(visitor) + self.deserialize_map(visitor) + }, + Level::Sequence(_) => { + self.deserialize_seq(visitor) + + }, + Level::Flat(x) => { + visitor.visit_string(x) + }, + Level::Invalid(e) => { + Err(de::Error::custom(e)) + } + } + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + match self.0 { + Level::Nested(map) => { + visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))) + }, + Level::Sequence(x) => { + visitor.visit_seq(LevelSeq(x.into_iter())) + }, + Level::Invalid(e) => { + Err(de::Error::custom(e)) + }, + x => { + visitor.visit_seq(LevelSeq(vec![x].into_iter())) + }, + } + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + match self.0 { + Level::Flat(ref x) if x == "" => { + visitor.visit_none() + }, + _ => { + visitor.visit_some(self) + }, + } + } + + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + match self.0 { + Level::Nested(map) => { + Deserializer::with_map(map).deserialize_enum(name, variants, visitor) + }, + Level::Flat(_) => { + visitor.visit_enum(self) + }, + _ => { + Err(de::Error::custom("value does not appear to be a sequence")) + }, + } + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + where V: de::Visitor<'de>, + { + self.to_deserializer()?.deserialize_map(visitor) + + } + + fn deserialize_struct<V>(self, + name: &'static str, + fields: &'static [&'static str], + visitor: V) + -> Result<V::Value> + where V: de::Visitor<'de>, + { + self.to_deserializer()?.deserialize_struct(name, fields, visitor) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple<V>( + self, + _len: usize, + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + // self.to_deserializer()?.deserialize_tuple(len, visitor) + self.deserialize_seq(visitor) + + } + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + _len: usize, + visitor: V + ) -> Result<V::Value> + where V: de::Visitor<'de> + { + self.deserialize_seq(visitor) + } + + deserialize_primitive!(bool, deserialize_bool, visit_bool); + deserialize_primitive!(i8, deserialize_i8, visit_i8); + deserialize_primitive!(i16, deserialize_i16, visit_i16); + deserialize_primitive!(i32, deserialize_i32, visit_i32); + deserialize_primitive!(i64, deserialize_i64, visit_i64); + deserialize_primitive!(u8, deserialize_u8, visit_u8); + deserialize_primitive!(u16, deserialize_u16, visit_u16); + deserialize_primitive!(u32, deserialize_u32, visit_u32); + deserialize_primitive!(u64, deserialize_u64, visit_u64); + deserialize_primitive!(f32, deserialize_f32, visit_f32); + deserialize_primitive!(f64, deserialize_f64, visit_f64); + + + forward_to_deserialize_any! { + char + str + string + unit + bytes + byte_buf + unit_struct + // newtype_struct + // tuple_struct + identifier + // tuple + // enum + ignored_any + } +} + + +macro_rules! forward_parsable_to_deserialize_any { + ($($ty:ident => $meth:ident,)*) => { + $( + fn $meth<V>(self, visitor: V) -> Result<V::Value> 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<V>(self, visitor: V) -> Result<V::Value> + 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, + } + +} diff --git a/src/de/parse.rs b/src/de/parse.rs new file mode 100644 index 0000000..7a647db --- /dev/null +++ b/src/de/parse.rs @@ -0,0 +1,359 @@ +use serde::de; + +use super::*; + +/// To override the default serialization parameters, first construct a new +/// Config. +/// +/// A `max_depth` of 0 implies no nesting: the result will be a flat map. +/// This is mostly useful when the maximum nested depth is known beforehand, +/// to prevent denial of service attacks by providing incredibly deeply nested +/// inputs. +/// +/// ``` +/// use serde_qs::de::Config; +/// use std::collections::HashMap; +/// +/// let config = Config::with_max_depth(0); +/// let map: HashMap<String, String> = config.deserialize_str("a[b][c]=1") +/// .unwrap(); +/// assert_eq!(map.get("a[b][c]").unwrap(), "1"); +/// +/// let config = Config::with_max_depth(10); +/// let map: HashMap<String, HashMap<String, HashMap<String, String>>> = +/// config.deserialize_str("a[b][c]=1").unwrap(); +/// assert_eq!(map.get("a").unwrap().get("b").unwrap().get("c").unwrap(), "1"); +/// ``` +/// +pub struct Config { + /// Specifies the maximum depth key that `serde_qs` will attempt to + /// deserialize. Default is 5. + max_depth: usize, +} + +impl Default for Config { + fn default() -> Self { + Config { max_depth: 5 } + } +} + +impl Config { + pub fn with_max_depth(depth: usize) -> Config { + Config { + max_depth: depth + } + } + + pub fn max_depth(&self) -> usize { + self.max_depth + } +} + +impl Config { + pub fn deserialize_bytes<'de, T: de::Deserialize<'de>>(&self, + input: &[u8]) + -> Result<T> { + T::deserialize(Deserializer::with_config(self, input)) + } + + pub fn deserialize_str<'de, T: de::Deserialize<'de>>(&self, + input: &str) + -> Result<T> { + self.deserialize_bytes(input.as_bytes()) + } + + pub fn deserialize_reader<'de, T, R>(&self, mut reader: R) -> Result<T> + where T: de::Deserialize<'de>, + R: Read, + { + let mut buf = vec![]; + reader.read_to_end(&mut buf) + .map_err(|e| { + ErrorKind::Io(e) + })?; + self.deserialize_bytes(&buf) + } +} + + +macro_rules! tu { + ($x:expr) => ( + match $x { + Some(x) => x, + None => return Err( + de::Error::custom("query string ended before expected")) + } + ) +} + +use std::iter::Iterator; +use std::str; + +pub struct Parser<I: Iterator<Item = u8>> { + inner: I, + acc: Vec<u8>, + peeked: Option<u8>, + depth: usize, +} + +impl<I: Iterator<Item = u8>> Iterator for Parser<I> { + type Item = u8; + #[inline] + fn next(&mut self) -> Option<Self::Item> { + self.inner.next() + } +} + + +fn insert_into_map(node: &mut Level, key: String, value: String) { + if let Level::Nested(ref mut map) = *node { + match map.entry(key) { + Entry::Occupied(mut o) => { + o.insert(Level::Invalid("Multiple values for one key")); + }, + Entry::Vacant(vm) => { + vm.insert(Level::Flat(value)); + }, + } + } else { + let mut map = BTreeMap::default(); + map.insert(key, Level::Flat(value)); + *node = Level::Nested(map); + } +} + +impl<I: Iterator<Item = u8>> Parser<I> { + pub fn new(inner: I, acc: Vec<u8>, peeked: Option<u8>, depth: usize) -> Self { + Parser { + inner, acc, peeked, depth + } + } + + pub fn to_deserializer(mut self) -> Deserializer { + let map = BTreeMap::default(); + let mut root = Level::Nested(map); + while let Ok(x) = self.parse(&mut root) { + if !x { + break; + } + } + let iter = match root { + Level::Nested(map) => map.into_iter(), + _ => panic!(""), + }; + Deserializer { + iter: iter, + value: None, + } + } + + #[inline] + fn peek(&mut self) -> Option<<Self as Iterator>::Item> { + if !self.acc.is_empty() { + self.peeked + } else if let Some(x) = self.inner.next() { + self.acc.push(x); + self.peeked = Some(x); + Some(x) + } else { + None + } + } + + fn parse_key(&mut self, + end_on: u8, + consume: bool) + -> Result<String> { + loop { + if let Some(x) = self.next() { + match x { + x if x == end_on => { + let res = String::from_utf8(self.acc.split_off(0)); + self.acc.clear(); + + // Add this character back to the buffer for peek. + if !consume { + self.acc.push(x); + self.peeked = Some(x); + } + return res.map_err(|_| de::Error::custom("blah")); + }, + b'=' => { + // Allow the '=' byte when parsing keys within [] + if end_on == b']' { + self.acc.push(b'='); + } else { + let res = String::from_utf8(self.acc.split_off(0)); + self.acc.clear(); + + // Add this character back to the buffer for peek. + self.acc.push(b'='); + self.peeked = Some(b'='); + + return res.map_err(|_| de::Error::custom("blah")); + } + }, + b' ' => { + self.acc.push(b' '); + }, + b'&' => { + let res = String::from_utf8(self.acc.split_off(0)); + self.acc.clear(); + self.acc.push(b'&'); + self.peeked = Some(b'&'); + return res.map_err(|_| de::Error::custom("blah")); + }, + x @ 0x20...0x7e => { + self.acc.push(x); + }, + _ => { + return Err(de::Error::custom("unexpected character \ + in query string.")); + }, + } + } else { + // End of string. + let res = String::from_utf8(self.acc.split_off(0)); + self.acc.clear(); + return res.map_err(|_| de::Error::custom("blah")); + } + } + } + + fn parse_map_value(&mut self, + key: String, + node: &mut Level) + -> Result<()> { + if let Some(x) = self.peek() { + match x { + b'=' => { + self.acc.clear(); + for b in self.inner.by_ref().take_while(|b| b != &b'&') { + if b == b'+' { + self.acc.push(b' '); + } else { + self.acc.push(b); + } + } + let value = String::from_utf8(self.acc.split_off(0)); + let value = value.map_err(|e| ErrorKind::Utf8(e))?; + // Reached the end of the key string + insert_into_map(node, key, value); + Ok(()) + }, + b'&' => { + insert_into_map(node, key, "".to_string()); + Ok(()) + }, + b'[' => { + if let Level::Invalid(_) = *node { + *node = Level::Nested(BTreeMap::default()); + } + if let Level::Nested(ref mut map) = *node { + self.depth -= 1; + self.parse(map.entry(key) + .or_insert(Level::Invalid("uninitialised")))?; + Ok(()) + } else { + Err(de::Error::custom(format!("tried to insert a \ + new key into {:?}", + node))) + } + }, + _ => { + panic!("Unexpected character"); + }, + } + } else { + insert_into_map(node, key, "".to_string()); + Ok(()) + } + } + + fn parse_seq_value(&mut self, node: &mut Level) -> Result<()> { + match tu!(self.peek()) { + b'=' => { + self.acc.clear(); + for b in self.inner.by_ref().take_while(|b| b != &b'&') { + self.acc.push(b); + } + let value = String::from_utf8(self.acc.split_off(0)) + .map(|s| s.into()); + let value = value.map_err(|e| ErrorKind::Utf8(e))?; + // Reached the end of the key string + if let Level::Sequence(ref mut seq) = *node { + seq.push(Level::Flat(value)); + } else { + let mut seq = Vec::new(); + seq.push(Level::Flat(value)); + *node = Level::Sequence(seq); + } + Ok(()) + }, + _ => { + Err(de::Error::custom("non-indexed sequence of structs not \ + supported")) + }, + } + } + + + pub fn parse(&mut self, node: &mut Level) -> Result<bool> { + // First character determines parsing type + if self.depth == 0 { + let key = self.parse_key(b'\x00', true)?; + self.parse_map_value(key.into(), node)?; + self.depth += 1; + return Ok(true); + } + match self.peek() { + Some(x) => { + match x { + b'[' => { + self.acc.clear(); + // let _ = self.next(); + match tu!(self.peek()) { + // key is of the form "[...", not really allowed. + b'[' => { + panic!(""); + + }, + // key is simply "[]", so treat as a seq. + b']' => { + self.acc.clear(); + self.parse_seq_value(node)?; + self.depth += 1; + Ok(true) + + }, + // Key is "[a..." so parse up to the closing "]" + 0x20...0x7e => { + let key = self.parse_key(b']', true)?; + self.parse_map_value(key.into(), node)?; + self.depth += 1; + Ok(true) + + }, + _ => { + panic!(""); + }, + } + }, + // This means the key should be a root key + // of the form "abc" or "abc[...]" + 0x20...0x7e => { + let key = self.parse_key(b'[', false)?; + self.parse_map_value(key.into(), node)?; + self.depth += 1; + Ok(true) + }, + _ => { + panic!(""); + }, + } + }, + // Ran out of characters to parse + None => Ok(false), + } + } +} @@ -74,4 +74,6 @@ pub mod ser; #[doc(inline)] pub use de::{Deserializer, from_bytes, from_reader, from_str}; #[doc(inline)] +pub use de::Config; +#[doc(inline)] pub use ser::{QsSerializer, to_string}; |