summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Scott <sam.scott89@gmail.com>2017-05-20 22:57:58 +0100
committerSam Scott <sam.scott89@gmail.com>2017-05-20 22:57:58 +0100
commit661cc9697a1c31abe786e45e43072800b6641871 (patch)
tree9d7d20656320d4bf5fb437d8f8d13b0e41131571 /src
parent6e71ba43eb6bd62f2b567224e387333016bd3a5c (diff)
Organisational changes.
Diffstat (limited to 'src')
-rw-r--r--src/de.rs975
-rw-r--r--src/de/mod.rs652
-rw-r--r--src/de/parse.rs359
-rw-r--r--src/lib.rs2
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),
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 7269046..10b30f3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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};