Skip to main content

serde_urlencoded/
de.rs

1//! Deserialization support for the `application/x-www-form-urlencoded` format.
2
3use form_urlencoded::Parse as UrlEncodedParse;
4use form_urlencoded::parse;
5use serde::de::Error as de_Error;
6use serde::de::value::MapDeserializer;
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        u128
134        i8
135        i16
136        i32
137        i64
138        i128
139        f32
140        f64
141        char
142        str
143        string
144        option
145        bytes
146        byte_buf
147        unit_struct
148        newtype_struct
149        tuple_struct
150        struct
151        identifier
152        tuple
153        enum
154        ignored_any
155    }
156}
157
158struct PartIterator<'de>(UrlEncodedParse<'de>);
159
160impl<'de> Iterator for PartIterator<'de> {
161    type Item = (Part<'de>, Part<'de>);
162
163    fn next(&mut self) -> Option<Self::Item> {
164        self.0.next().map(|(k, v)| (Part(k), Part(v)))
165    }
166}
167
168struct Part<'de>(Cow<'de, str>);
169
170impl<'de> IntoDeserializer<'de> for Part<'de> {
171    type Deserializer = Self;
172
173    fn into_deserializer(self) -> Self::Deserializer {
174        self
175    }
176}
177
178macro_rules! forward_parsed_value {
179    ($($ty:ident => $method:ident,)*) => {
180        $(
181            fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
182                where V: de::Visitor<'de>
183            {
184                match self.0.parse::<$ty>() {
185                    Ok(val) => val.into_deserializer().$method(visitor),
186                    Err(e) => Err(de::Error::custom(e))
187                }
188            }
189        )*
190    }
191}
192
193impl<'de> de::Deserializer<'de> for Part<'de> {
194    type Error = Error;
195
196    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
197    where
198        V: de::Visitor<'de>,
199    {
200        match self.0 {
201            Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
202            Cow::Owned(value) => visitor.visit_string(value),
203        }
204    }
205
206    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
207    where
208        V: de::Visitor<'de>,
209    {
210        visitor.visit_some(self)
211    }
212
213    fn deserialize_enum<V>(
214        self,
215        _name: &'static str,
216        _variants: &'static [&'static str],
217        visitor: V,
218    ) -> Result<V::Value, Self::Error>
219    where
220        V: de::Visitor<'de>,
221    {
222        visitor.visit_enum(ValueEnumAccess(self.0))
223    }
224
225    fn deserialize_newtype_struct<V>(
226        self,
227        _name: &'static str,
228        visitor: V,
229    ) -> Result<V::Value, Self::Error>
230    where
231        V: de::Visitor<'de>,
232    {
233        visitor.visit_newtype_struct(self)
234    }
235
236    forward_to_deserialize_any! {
237        char
238        str
239        string
240        unit
241        bytes
242        byte_buf
243        unit_struct
244        tuple_struct
245        struct
246        identifier
247        tuple
248        ignored_any
249        seq
250        map
251    }
252
253    forward_parsed_value! {
254        bool => deserialize_bool,
255        u8 => deserialize_u8,
256        u16 => deserialize_u16,
257        u32 => deserialize_u32,
258        u64 => deserialize_u64,
259        u128 => deserialize_u128,
260        i8 => deserialize_i8,
261        i16 => deserialize_i16,
262        i32 => deserialize_i32,
263        i64 => deserialize_i64,
264        i128 => deserialize_i128,
265        f32 => deserialize_f32,
266        f64 => deserialize_f64,
267    }
268}
269
270struct ValueEnumAccess<'de>(Cow<'de, str>);
271
272impl<'de> de::EnumAccess<'de> for ValueEnumAccess<'de> {
273    type Error = Error;
274    type Variant = UnitOnlyVariantAccess;
275
276    fn variant_seed<V>(
277        self,
278        seed: V,
279    ) -> Result<(V::Value, Self::Variant), Self::Error>
280    where
281        V: de::DeserializeSeed<'de>,
282    {
283        let variant = seed.deserialize(self.0.into_deserializer())?;
284        Ok((variant, UnitOnlyVariantAccess))
285    }
286}
287
288struct UnitOnlyVariantAccess;
289
290impl<'de> de::VariantAccess<'de> for UnitOnlyVariantAccess {
291    type Error = Error;
292
293    fn unit_variant(self) -> Result<(), Self::Error> {
294        Ok(())
295    }
296
297    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
298    where
299        T: de::DeserializeSeed<'de>,
300    {
301        Err(Error::custom("expected unit variant"))
302    }
303
304    fn tuple_variant<V>(
305        self,
306        _len: usize,
307        _visitor: V,
308    ) -> Result<V::Value, Self::Error>
309    where
310        V: de::Visitor<'de>,
311    {
312        Err(Error::custom("expected unit variant"))
313    }
314
315    fn struct_variant<V>(
316        self,
317        _fields: &'static [&'static str],
318        _visitor: V,
319    ) -> Result<V::Value, Self::Error>
320    where
321        V: de::Visitor<'de>,
322    {
323        Err(Error::custom("expected unit variant"))
324    }
325}