diff options
Diffstat (limited to 'src/de.rs')
-rw-r--r-- | src/de.rs | 975 |
1 files changed, 0 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, - } - -} |