summaryrefslogtreecommitdiff
path: root/src/de
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/de
parent6e71ba43eb6bd62f2b567224e387333016bd3a5c (diff)
Organisational changes.
Diffstat (limited to 'src/de')
-rw-r--r--src/de/mod.rs652
-rw-r--r--src/de/parse.rs359
2 files changed, 1011 insertions, 0 deletions
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),
+ }
+ }
+}