serde_qs/de/
mod.rs

1//! Deserialization support for querystrings.
2
3//! ### An overview of the design of `QsDeserializer`
4//!
5//! This code is designed to handle non-ordered query parameters. For example,
6//! `struct { a: Vec<u8>, b: String }` might be serialized as either
7//! `a[0]=1&a[1]=2&b=Hello or a[1]=2&b=Hello&a[0]=1`.
8//!
9//! In order to cover the latter case, we have two options: scan through the
10//! string each time we need to find a particular key - worst case O(n^2 )
11//! running time; or pre-parse the list into a map structure, and then
12//! deserialize the map.
13//!
14//! We opt for the latter. But a TODO is implement the first case, which could
15//! potentially be more desirable, especially when the keys are known to be in
16//! order.
17//!
18//! The `parse` module handles this step of deserializing a querystring into the
19//! map structure. This uses `rust_url::percent_encoding` to handle
20//! first converting the string.
21//!
22//! From here, there are two main `Deserializer` objects: `QsDeserializer` and
23//! `LevelDeserializer`.
24//!
25//! The former is the top-level deserializer which is effectively only capable
26//! of deserializing map-like objects (i.e. those with (key, value) pairs).
27//! Hence, structs, maps, and enums are supported at this level.
28//!
29//! Each key is a `String`, and deserialized from a `String`. The values are
30//! `Level` elements. This is a recursive structure which can either be a "flat
31//! value", i.e. just a string, or a sequence or map of these elements. This can
32//! be thought of as similar to the `serde_json::Value` enum.
33//!
34//! Each `Level` can be deserialized through `LevelDeserializer`. This will
35//! recursively call back to the top level `QsDeserializer` for maps, or when
36//! `Level` is a flat value it will attempt to deserialize it to a primitive via
37//! `ParsableStringDeserializer`.
38
39mod parse;
40
41use crate::error::*;
42
43use serde::de;
44use serde::de::IntoDeserializer;
45
46use std::borrow::Cow;
47use std::collections::btree_map::{BTreeMap, Entry, IntoIter};
48
49/// To override the default serialization parameters, first construct a new
50/// Config.
51///
52/// The `strict` parameter controls whether the deserializer will tolerate
53/// encoded brackets as part of the key. For example, serializing the field
54/// `a = vec![12]` might give `a[0]=12`. In strict mode, the only string accepted
55/// will be this string, whereas in non-strict mode, this can also be deserialized
56/// from `a%5B0%5D=12`. Strict mode is more accurate for cases where it a field
57/// may contain square brackets.
58/// In non-strict mode, the deserializer will generally tolerate unexpected
59/// characters.
60///
61/// A `max_depth` of 0 implies no nesting: the result will be a flat map.
62/// This is mostly useful when the maximum nested depth is known beforehand,
63/// to prevent denial of service attacks by providing incredibly deeply nested
64/// inputs.
65///
66/// The default value for `max_depth` is 5, and the default mode is `strict=true`.
67///
68/// ```
69/// use serde_qs::Config;
70/// use std::collections::HashMap;
71///
72/// let config = Config::new(0, true);
73/// let map: HashMap<String, String> = config.deserialize_str("a[b][c]=1")
74///                                          .unwrap();
75/// assert_eq!(map.get("a[b][c]").unwrap(), "1");
76///
77/// let config = Config::new(10, true);
78/// let map: HashMap<String, HashMap<String, HashMap<String, String>>> =
79///             config.deserialize_str("a[b][c]=1").unwrap();
80/// assert_eq!(map.get("a").unwrap().get("b").unwrap().get("c").unwrap(), "1");
81/// ```
82///
83pub struct Config {
84    /// Specifies the maximum depth key that `serde_qs` will attempt to
85    /// deserialize. Default is 5.
86    max_depth: usize,
87    /// Strict deserializing mode will not tolerate encoded brackets.
88    strict: bool,
89}
90
91impl Default for Config {
92    fn default() -> Self {
93        Self::new(5, true)
94    }
95}
96
97impl Config {
98    /// Create a new `Config` with the specified `max_depth` and `strict` mode.
99    pub fn new(max_depth: usize, strict: bool) -> Self {
100        Self { max_depth, strict }
101    }
102
103    /// Get maximum depth parameter.
104    fn max_depth(&self) -> usize {
105        self.max_depth
106    }
107}
108
109impl Config {
110    /// Deserializes a querystring from a `&[u8]` using this `Config`.
111    pub fn deserialize_bytes<'de, T: de::Deserialize<'de>>(&self, input: &'de [u8]) -> Result<T> {
112        T::deserialize(QsDeserializer::with_config(self, input)?)
113    }
114
115    // pub fn deserialize_bytes_sloppy<T: de::DeserializeOwned>(&self, input: &[u8])
116    //     -> Result<T>
117    // {
118    //     let buf = String::from_utf8(input.to_vec())?;
119    //     let buf = buf.replace("%5B", "[").replace("%5D", "]").into_bytes();
120    //     let deser = QsDeserializer::with_config(self, &buf)?;
121    //     T::deserialize(deser)
122    // }
123
124    /// Deserializes a querystring from a `&str` using this `Config`.
125    pub fn deserialize_str<'de, T: de::Deserialize<'de>>(&self, input: &'de str) -> Result<T> {
126        self.deserialize_bytes(input.as_bytes())
127    }
128}
129
130/// Deserializes a querystring from a `&[u8]`.
131///
132/// ```
133/// # #[macro_use]
134/// # extern crate serde_derive;
135/// # extern crate serde_qs;
136/// #[derive(Debug, Deserialize, PartialEq, Serialize)]
137/// struct Query {
138///     name: String,
139///     age: u8,
140///     occupation: String,
141/// }
142///
143/// # fn main(){
144/// let q =  Query {
145///     name: "Alice".to_owned(),
146///     age: 24,
147///     occupation: "Student".to_owned(),
148/// };
149///
150/// assert_eq!(
151///     serde_qs::from_bytes::<Query>(
152///         "name=Alice&age=24&occupation=Student".as_bytes()
153///     ).unwrap(), q);
154/// # }
155/// ```
156pub fn from_bytes<'de, T: de::Deserialize<'de>>(input: &'de [u8]) -> Result<T> {
157    Config::default().deserialize_bytes(input)
158}
159
160/// Deserializes a querystring from a `&str`.
161///
162/// ```
163/// # #[macro_use]
164/// # extern crate serde_derive;
165/// # extern crate serde_qs;
166/// #[derive(Debug, Deserialize, PartialEq, Serialize)]
167/// struct Query {
168///     name: String,
169///     age: u8,
170///     occupation: String,
171/// }
172///
173/// # fn main(){
174/// let q =  Query {
175///     name: "Alice".to_owned(),
176///     age: 24,
177///     occupation: "Student".to_owned(),
178/// };
179///
180/// assert_eq!(
181///     serde_qs::from_str::<Query>("name=Alice&age=24&occupation=Student").unwrap(),
182///     q);
183/// # }
184/// ```
185pub fn from_str<'de, T: de::Deserialize<'de>>(input: &'de str) -> Result<T> {
186    from_bytes(input.as_bytes())
187}
188
189/// A deserializer for the querystring format.
190///
191/// Supported top-level outputs are structs and maps.
192pub(crate) struct QsDeserializer<'a> {
193    iter: IntoIter<Cow<'a, str>, Level<'a>>,
194    value: Option<Level<'a>>,
195}
196
197#[derive(Debug)]
198enum Level<'a> {
199    Nested(BTreeMap<Cow<'a, str>, Level<'a>>),
200    OrderedSeq(BTreeMap<usize, Level<'a>>),
201    Sequence(Vec<Level<'a>>),
202    Flat(Cow<'a, str>),
203    Invalid(&'static str),
204    Uninitialised,
205}
206
207impl<'a> QsDeserializer<'a> {
208    fn with_map(map: BTreeMap<Cow<'a, str>, Level<'a>>) -> Self {
209        QsDeserializer {
210            iter: map.into_iter(),
211            value: None,
212        }
213    }
214
215    /// Returns a new `QsDeserializer<'a>`.
216    fn with_config(config: &Config, input: &'a [u8]) -> Result<Self> {
217        parse::Parser::new(input, config.max_depth(), config.strict).as_deserializer()
218    }
219}
220
221impl<'de> de::Deserializer<'de> for QsDeserializer<'de> {
222    type Error = Error;
223
224    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
225    where
226        V: de::Visitor<'de>,
227    {
228        Err(Error::top_level("primitive"))
229    }
230
231    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
232    where
233        V: de::Visitor<'de>,
234    {
235        visitor.visit_map(self)
236    }
237
238    fn deserialize_struct<V>(
239        self,
240        _name: &'static str,
241        _fields: &'static [&'static str],
242        visitor: V,
243    ) -> Result<V::Value>
244    where
245        V: de::Visitor<'de>,
246    {
247        self.deserialize_map(visitor)
248    }
249
250    /// Throws an error.
251    ///
252    /// Sequences are not supported at the top level.
253    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value>
254    where
255        V: de::Visitor<'de>,
256    {
257        Err(Error::top_level("sequence"))
258    }
259
260    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
261    where
262        V: de::Visitor<'de>,
263    {
264        self.deserialize_map(visitor)
265    }
266
267    /// Throws an error.
268    ///
269    /// Tuples are not supported at the top level.
270    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
271    where
272        V: de::Visitor<'de>,
273    {
274        Err(Error::top_level("tuple"))
275    }
276
277    /// Throws an error.
278    ///
279    /// TupleStructs are not supported at the top level.
280    fn deserialize_tuple_struct<V>(
281        self,
282        _name: &'static str,
283        _len: usize,
284        _visitor: V,
285    ) -> Result<V::Value>
286    where
287        V: de::Visitor<'de>,
288    {
289        Err(Error::top_level("tuple struct"))
290    }
291
292    fn deserialize_enum<V>(
293        self,
294        _name: &'static str,
295        _variants: &'static [&'static str],
296        visitor: V,
297    ) -> Result<V::Value>
298    where
299        V: de::Visitor<'de>,
300    {
301        visitor.visit_enum(self)
302    }
303
304    forward_to_deserialize_any! {
305        bool
306        u8
307        u16
308        u32
309        u64
310        i8
311        i16
312        i32
313        i64
314        f32
315        f64
316        char
317        str
318        string
319        unit
320        option
321        bytes
322        byte_buf
323        unit_struct
324        identifier
325        ignored_any
326    }
327}
328
329impl<'de> de::MapAccess<'de> for QsDeserializer<'de> {
330    type Error = Error;
331
332    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
333    where
334        K: de::DeserializeSeed<'de>,
335    {
336        if let Some((key, value)) = self.iter.next() {
337            self.value = Some(value);
338            return seed.deserialize(ParsableStringDeserializer(key)).map(Some);
339        };
340        Ok(None)
341    }
342
343    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
344    where
345        V: de::DeserializeSeed<'de>,
346    {
347        if let Some(v) = self.value.take() {
348            seed.deserialize(LevelDeserializer(v))
349        } else {
350            Err(de::Error::custom(
351                "Somehow the list was empty after a \
352                 non-empty key was returned",
353            ))
354        }
355    }
356}
357
358impl<'de> de::EnumAccess<'de> for QsDeserializer<'de> {
359    type Error = Error;
360    type Variant = Self;
361
362    fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant)>
363    where
364        V: de::DeserializeSeed<'de>,
365    {
366        if let Some((key, value)) = self.iter.next() {
367            self.value = Some(value);
368            Ok((seed.deserialize(ParsableStringDeserializer(key))?, self))
369        } else {
370            Err(de::Error::custom("No more values"))
371        }
372    }
373}
374
375impl<'de> de::VariantAccess<'de> for QsDeserializer<'de> {
376    type Error = Error;
377    fn unit_variant(self) -> Result<()> {
378        Ok(())
379    }
380
381    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
382    where
383        T: de::DeserializeSeed<'de>,
384    {
385        if let Some(value) = self.value {
386            seed.deserialize(LevelDeserializer(value))
387        } else {
388            Err(de::Error::custom("no value to deserialize"))
389        }
390    }
391    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
392    where
393        V: de::Visitor<'de>,
394    {
395        if let Some(value) = self.value {
396            de::Deserializer::deserialize_seq(LevelDeserializer(value), visitor)
397        } else {
398            Err(de::Error::custom("no value to deserialize"))
399        }
400    }
401    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
402    where
403        V: de::Visitor<'de>,
404    {
405        if let Some(value) = self.value {
406            de::Deserializer::deserialize_map(LevelDeserializer(value), visitor)
407        } else {
408            Err(de::Error::custom("no value to deserialize"))
409        }
410    }
411}
412
413impl<'de> de::EnumAccess<'de> for LevelDeserializer<'de> {
414    type Error = Error;
415    type Variant = Self;
416
417    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
418    where
419        V: de::DeserializeSeed<'de>,
420    {
421        match self.0 {
422            Level::Flat(x) => Ok((
423                seed.deserialize(ParsableStringDeserializer(x))?,
424                LevelDeserializer(Level::Invalid(
425                    "this value can only \
426                     deserialize to a \
427                     UnitVariant",
428                )),
429            )),
430            _ => Err(de::Error::custom(
431                "this value can only deserialize to a \
432                 UnitVariant",
433            )),
434        }
435    }
436}
437
438impl<'de> de::VariantAccess<'de> for LevelDeserializer<'de> {
439    type Error = Error;
440    fn unit_variant(self) -> Result<()> {
441        Ok(())
442    }
443
444    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
445    where
446        T: de::DeserializeSeed<'de>,
447    {
448        seed.deserialize(self)
449    }
450    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
451    where
452        V: de::Visitor<'de>,
453    {
454        de::Deserializer::deserialize_seq(self, visitor)
455    }
456    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
457    where
458        V: de::Visitor<'de>,
459    {
460        de::Deserializer::deserialize_map(self, visitor)
461    }
462}
463
464struct LevelSeq<'a, I: Iterator<Item = Level<'a>>>(I);
465
466impl<'de, I: Iterator<Item = Level<'de>>> de::SeqAccess<'de> for LevelSeq<'de, I> {
467    type Error = Error;
468    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
469    where
470        T: de::DeserializeSeed<'de>,
471    {
472        if let Some(v) = self.0.next() {
473            seed.deserialize(LevelDeserializer(v)).map(Some)
474        } else {
475            Ok(None)
476        }
477    }
478}
479
480struct LevelDeserializer<'a>(Level<'a>);
481
482macro_rules! deserialize_primitive {
483    ($ty:ident, $method:ident, $visit_method:ident) => {
484        fn $method<V>(self, visitor: V) -> Result<V::Value>
485        where
486            V: de::Visitor<'de>,
487        {
488            match self.0 {
489                Level::Nested(_) => Err(de::Error::custom(format!(
490                    "Expected: {:?}, got a Map",
491                    stringify!($ty)
492                ))),
493                Level::OrderedSeq(_) => Err(de::Error::custom(format!(
494                    "Expected: {:?}, got an OrderedSequence",
495                    stringify!($ty)
496                ))),
497                Level::Sequence(_) => Err(de::Error::custom(format!(
498                    "Expected: {:?}, got a Sequence",
499                    stringify!($ty)
500                ))),
501                Level::Flat(x) => ParsableStringDeserializer(x).$method(visitor),
502                Level::Invalid(e) => Err(de::Error::custom(e)),
503                Level::Uninitialised => Err(de::Error::custom(
504                    "attempted to deserialize unitialised value",
505                )),
506            }
507        }
508    };
509}
510
511impl<'a> LevelDeserializer<'a> {
512    fn into_deserializer(self) -> Result<QsDeserializer<'a>> {
513        match self.0 {
514            Level::Nested(map) => Ok(QsDeserializer::with_map(map)),
515            Level::OrderedSeq(map) => Ok(QsDeserializer::with_map(
516                map.into_iter()
517                    .map(|(k, v)| (Cow::Owned(k.to_string()), v))
518                    .collect(),
519            )),
520            Level::Invalid(e) => Err(de::Error::custom(e)),
521            l => Err(de::Error::custom(format!(
522                "could not convert {:?} to \
523                 QsDeserializer<'a>",
524                l
525            ))),
526        }
527    }
528}
529
530impl<'de> de::Deserializer<'de> for LevelDeserializer<'de> {
531    type Error = Error;
532
533    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
534    where
535        V: de::Visitor<'de>,
536    {
537        match self.0 {
538            Level::Nested(_) => self.into_deserializer()?.deserialize_map(visitor),
539            Level::OrderedSeq(map) => visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))),
540            Level::Sequence(seq) => visitor.visit_seq(LevelSeq(seq.into_iter())),
541            Level::Flat(x) => match x {
542                Cow::Owned(s) => visitor.visit_string(s),
543                Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
544            },
545            Level::Invalid(e) => Err(de::Error::custom(e)),
546            Level::Uninitialised => Err(de::Error::custom(
547                "attempted to deserialize unitialised \
548                 value",
549            )),
550        }
551    }
552
553    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
554    where
555        V: de::Visitor<'de>,
556    {
557        match self.0 {
558            Level::Flat(ref x) if x == "" => visitor.visit_none(),
559            _ => visitor.visit_some(self),
560        }
561    }
562
563    fn deserialize_enum<V>(
564        self,
565        name: &'static str,
566        variants: &'static [&'static str],
567        visitor: V,
568    ) -> Result<V::Value>
569    where
570        V: de::Visitor<'de>,
571    {
572        match self.0 {
573            Level::Nested(map) => {
574                QsDeserializer::with_map(map).deserialize_enum(name, variants, visitor)
575            }
576            Level::Flat(_) => visitor.visit_enum(self),
577            x => Err(de::Error::custom(format!(
578                "{:?} does not appear to be \
579                 an enum",
580                x
581            ))),
582        }
583    }
584
585    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
586    where
587        V: de::Visitor<'de>,
588    {
589        match self.0 {
590            Level::Nested(_) => self.into_deserializer()?.deserialize_map(visitor),
591            Level::OrderedSeq(map) => visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))),
592            Level::Sequence(seq) => visitor.visit_seq(LevelSeq(seq.into_iter())),
593            Level::Flat(_) => {
594                // For a newtype_struct, attempt to deserialize a flat value as a
595                // single element sequence.
596                visitor.visit_seq(LevelSeq(vec![self.0].into_iter()))
597            }
598            Level::Invalid(e) => Err(de::Error::custom(e)),
599            Level::Uninitialised => Err(de::Error::custom(
600                "attempted to deserialize unitialised \
601                 value",
602            )),
603        }
604    }
605
606    /// given the hint that this is a map, will first
607    /// attempt to deserialize ordered sequences into a map
608    /// otherwise, follows the any code path
609    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
610    where
611        V: de::Visitor<'de>,
612    {
613        match self.0 {
614            Level::OrderedSeq(_) => self.into_deserializer()?.deserialize_map(visitor),
615            _ => self.deserialize_any(visitor),
616        }
617    }
618
619    deserialize_primitive!(bool, deserialize_bool, visit_bool);
620    deserialize_primitive!(i8, deserialize_i8, visit_i8);
621    deserialize_primitive!(i16, deserialize_i16, visit_i16);
622    deserialize_primitive!(i32, deserialize_i32, visit_i32);
623    deserialize_primitive!(i64, deserialize_i64, visit_i64);
624    deserialize_primitive!(u8, deserialize_u8, visit_u8);
625    deserialize_primitive!(u16, deserialize_u16, visit_u16);
626    deserialize_primitive!(u32, deserialize_u32, visit_u32);
627    deserialize_primitive!(u64, deserialize_u64, visit_u64);
628    deserialize_primitive!(f32, deserialize_f32, visit_f32);
629    deserialize_primitive!(f64, deserialize_f64, visit_f64);
630
631    forward_to_deserialize_any! {
632        char
633        str
634        string
635        bytes
636        byte_buf
637        unit
638        unit_struct
639        // newtype_struct
640        tuple_struct
641        struct
642        identifier
643        tuple
644        ignored_any
645        seq
646        // map
647    }
648}
649
650macro_rules! forward_parsable_to_deserialize_any {
651    ($($ty:ident => $meth:ident,)*) => {
652        $(
653            fn $meth<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de> {
654                match self.0.parse::<$ty>() {
655                    Ok(val) => val.into_deserializer().$meth(visitor),
656                    Err(e) => Err(de::Error::custom(e))
657                }
658            }
659        )*
660    }
661}
662
663struct ParsableStringDeserializer<'a>(Cow<'a, str>);
664
665impl<'de> de::Deserializer<'de> for ParsableStringDeserializer<'de> {
666    type Error = Error;
667
668    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
669    where
670        V: de::Visitor<'de>,
671    {
672        self.0.into_deserializer().deserialize_any(visitor)
673    }
674
675    fn deserialize_enum<V>(
676        self,
677        _: &'static str,
678        _: &'static [&'static str],
679        visitor: V,
680    ) -> Result<V::Value>
681    where
682        V: de::Visitor<'de>,
683    {
684        visitor.visit_enum(LevelDeserializer(Level::Flat(self.0)))
685    }
686
687    forward_to_deserialize_any! {
688        map
689        struct
690        seq
691        option
692        char
693        str
694        string
695        unit
696        bytes
697        byte_buf
698        unit_struct
699        newtype_struct
700        tuple_struct
701        identifier
702        tuple
703        ignored_any
704    }
705
706    forward_parsable_to_deserialize_any! {
707        bool => deserialize_bool,
708        u8 => deserialize_u8,
709        u16 => deserialize_u16,
710        u32 => deserialize_u32,
711        u64 => deserialize_u64,
712        i8 => deserialize_i8,
713        i16 => deserialize_i16,
714        i32 => deserialize_i32,
715        i64 => deserialize_i64,
716        f32 => deserialize_f32,
717        f64 => deserialize_f64,
718    }
719}