serde_urlencoded/
de.rs

1//! Deserialization support for the `application/x-www-form-urlencoded` format.
2
3use form_urlencoded::parse;
4use form_urlencoded::Parse as UrlEncodedParse;
5use serde::de::value::MapDeserializer;
6use serde::de::Error as de_Error;
7use serde::de::{self, IntoDeserializer};
8use serde::forward_to_deserialize_any;
9use std::borrow::Cow;
10use std::io::Read;
11
12#[doc(inline)]
13pub use serde::de::value::Error;
14
15/// Deserializes a `application/x-www-form-urlencoded` value from a `&[u8]`.
16///
17/// ```
18/// let meal = vec![
19///     ("bread".to_owned(), "baguette".to_owned()),
20///     ("cheese".to_owned(), "comté".to_owned()),
21///     ("meat".to_owned(), "ham".to_owned()),
22///     ("fat".to_owned(), "butter".to_owned()),
23/// ];
24///
25/// assert_eq!(
26///     serde_urlencoded::from_bytes::<Vec<(String, String)>>(
27///         b"bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
28///     Ok(meal));
29/// ```
30pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, Error>
31where
32    T: de::Deserialize<'de>,
33{
34    T::deserialize(Deserializer::new(parse(input)))
35}
36
37/// Deserializes a `application/x-www-form-urlencoded` value from a `&str`.
38///
39/// ```
40/// let meal = vec![
41///     ("bread".to_owned(), "baguette".to_owned()),
42///     ("cheese".to_owned(), "comté".to_owned()),
43///     ("meat".to_owned(), "ham".to_owned()),
44///     ("fat".to_owned(), "butter".to_owned()),
45/// ];
46///
47/// assert_eq!(
48///     serde_urlencoded::from_str::<Vec<(String, String)>>(
49///         "bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
50///     Ok(meal));
51/// ```
52pub fn from_str<'de, T>(input: &'de str) -> Result<T, Error>
53where
54    T: de::Deserialize<'de>,
55{
56    from_bytes(input.as_bytes())
57}
58
59/// Convenience function that reads all bytes from `reader` and deserializes
60/// them with `from_bytes`.
61pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error>
62where
63    T: de::DeserializeOwned,
64    R: Read,
65{
66    let mut buf = vec![];
67    reader.read_to_end(&mut buf).map_err(|e| {
68        de::Error::custom(format_args!("could not read input: {}", e))
69    })?;
70    from_bytes(&buf)
71}
72
73/// A deserializer for the `application/x-www-form-urlencoded` format.
74///
75/// * Supported top-level outputs are structs, maps and sequences of pairs,
76///   with or without a given length.
77///
78/// * Main `deserialize` methods defers to `deserialize_map`.
79///
80/// * Everything else but `deserialize_seq` and `deserialize_seq_fixed_size`
81///   defers to `deserialize`.
82pub struct Deserializer<'de> {
83    inner: MapDeserializer<'de, PartIterator<'de>, Error>,
84}
85
86impl<'de> Deserializer<'de> {
87    /// Returns a new `Deserializer`.
88    pub fn new(parser: UrlEncodedParse<'de>) -> Self {
89        Deserializer {
90            inner: MapDeserializer::new(PartIterator(parser)),
91        }
92    }
93}
94
95impl<'de> de::Deserializer<'de> for Deserializer<'de> {
96    type Error = Error;
97
98    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
99    where
100        V: de::Visitor<'de>,
101    {
102        self.deserialize_map(visitor)
103    }
104
105    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
106    where
107        V: de::Visitor<'de>,
108    {
109        visitor.visit_map(self.inner)
110    }
111
112    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
113    where
114        V: de::Visitor<'de>,
115    {
116        visitor.visit_seq(self.inner)
117    }
118
119    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
120    where
121        V: de::Visitor<'de>,
122    {
123        self.inner.end()?;
124        visitor.visit_unit()
125    }
126
127    forward_to_deserialize_any! {
128        bool
129        u8
130        u16
131        u32
132        u64
133        i8
134        i16
135        i32
136        i64
137        f32
138        f64
139        char
140        str
141        string
142        option
143        bytes
144        byte_buf
145        unit_struct
146        newtype_struct
147        tuple_struct
148        struct
149        identifier
150        tuple
151        enum
152        ignored_any
153    }
154}
155
156struct PartIterator<'de>(UrlEncodedParse<'de>);
157
158impl<'de> Iterator for PartIterator<'de> {
159    type Item = (Part<'de>, Part<'de>);
160
161    fn next(&mut self) -> Option<Self::Item> {
162        self.0.next().map(|(k, v)| (Part(k), Part(v)))
163    }
164}
165
166struct Part<'de>(Cow<'de, str>);
167
168impl<'de> IntoDeserializer<'de> for Part<'de> {
169    type Deserializer = Self;
170
171    fn into_deserializer(self) -> Self::Deserializer {
172        self
173    }
174}
175
176macro_rules! forward_parsed_value {
177    ($($ty:ident => $method:ident,)*) => {
178        $(
179            fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
180                where V: de::Visitor<'de>
181            {
182                match self.0.parse::<$ty>() {
183                    Ok(val) => val.into_deserializer().$method(visitor),
184                    Err(e) => Err(de::Error::custom(e))
185                }
186            }
187        )*
188    }
189}
190
191impl<'de> de::Deserializer<'de> for Part<'de> {
192    type Error = Error;
193
194    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
195    where
196        V: de::Visitor<'de>,
197    {
198        match self.0 {
199            Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
200            Cow::Owned(value) => visitor.visit_string(value),
201        }
202    }
203
204    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
205    where
206        V: de::Visitor<'de>,
207    {
208        visitor.visit_some(self)
209    }
210
211    fn deserialize_enum<V>(
212        self,
213        _name: &'static str,
214        _variants: &'static [&'static str],
215        visitor: V,
216    ) -> Result<V::Value, Self::Error>
217    where
218        V: de::Visitor<'de>,
219    {
220        visitor.visit_enum(ValueEnumAccess(self.0))
221    }
222
223    fn deserialize_newtype_struct<V>(
224        self,
225        _name: &'static str,
226        visitor: V,
227    ) -> Result<V::Value, Self::Error>
228    where
229        V: de::Visitor<'de>,
230    {
231        visitor.visit_newtype_struct(self)
232    }
233
234    forward_to_deserialize_any! {
235        char
236        str
237        string
238        unit
239        bytes
240        byte_buf
241        unit_struct
242        tuple_struct
243        struct
244        identifier
245        tuple
246        ignored_any
247        seq
248        map
249    }
250
251    forward_parsed_value! {
252        bool => deserialize_bool,
253        u8 => deserialize_u8,
254        u16 => deserialize_u16,
255        u32 => deserialize_u32,
256        u64 => deserialize_u64,
257        i8 => deserialize_i8,
258        i16 => deserialize_i16,
259        i32 => deserialize_i32,
260        i64 => deserialize_i64,
261        f32 => deserialize_f32,
262        f64 => deserialize_f64,
263    }
264}
265
266struct ValueEnumAccess<'de>(Cow<'de, str>);
267
268impl<'de> de::EnumAccess<'de> for ValueEnumAccess<'de> {
269    type Error = Error;
270    type Variant = UnitOnlyVariantAccess;
271
272    fn variant_seed<V>(
273        self,
274        seed: V,
275    ) -> Result<(V::Value, Self::Variant), Self::Error>
276    where
277        V: de::DeserializeSeed<'de>,
278    {
279        let variant = seed.deserialize(self.0.into_deserializer())?;
280        Ok((variant, UnitOnlyVariantAccess))
281    }
282}
283
284struct UnitOnlyVariantAccess;
285
286impl<'de> de::VariantAccess<'de> for UnitOnlyVariantAccess {
287    type Error = Error;
288
289    fn unit_variant(self) -> Result<(), Self::Error> {
290        Ok(())
291    }
292
293    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
294    where
295        T: de::DeserializeSeed<'de>,
296    {
297        Err(Error::custom("expected unit variant"))
298    }
299
300    fn tuple_variant<V>(
301        self,
302        _len: usize,
303        _visitor: V,
304    ) -> Result<V::Value, Self::Error>
305    where
306        V: de::Visitor<'de>,
307    {
308        Err(Error::custom("expected unit variant"))
309    }
310
311    fn struct_variant<V>(
312        self,
313        _fields: &'static [&'static str],
314        _visitor: V,
315    ) -> Result<V::Value, Self::Error>
316    where
317        V: de::Visitor<'de>,
318    {
319        Err(Error::custom("expected unit variant"))
320    }
321}