1 | //! Deserialization support for the `application/x-www-form-urlencoded` format. |
2 | |
3 | use form_urlencoded::parse; |
4 | use form_urlencoded::Parse as UrlEncodedParse; |
5 | use serde::de::value::MapDeserializer; |
6 | use serde::de::Error as de_Error; |
7 | use serde::de::{self, IntoDeserializer}; |
8 | use serde::forward_to_deserialize_any; |
9 | use std::borrow::Cow; |
10 | use std::io::Read; |
11 | |
12 | #[doc (inline)] |
13 | pub 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 | /// ``` |
30 | pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, Error> |
31 | where |
32 | T: de::Deserialize<'de>, |
33 | { |
34 | T::deserialize(Deserializer::new(parser: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 | /// ``` |
52 | pub fn from_str<'de, T>(input: &'de str) -> Result<T, Error> |
53 | where |
54 | T: de::Deserialize<'de>, |
55 | { |
56 | from_bytes(input:input.as_bytes()) |
57 | } |
58 | |
59 | /// Convenience function that reads all bytes from `reader` and deserializes |
60 | /// them with `from_bytes`. |
61 | pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error> |
62 | where |
63 | T: de::DeserializeOwned, |
64 | R: Read, |
65 | { |
66 | let mut buf: Vec = vec![]; |
67 | reader.read_to_end(&mut buf).map_err(|e: Error| { |
68 | de::Error::custom(msg: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`. |
82 | pub struct Deserializer<'de> { |
83 | inner: MapDeserializer<'de, PartIterator<'de>, Error>, |
84 | } |
85 | |
86 | impl<'de> Deserializer<'de> { |
87 | /// Returns a new `Deserializer`. |
88 | pub fn new(parser: UrlEncodedParse<'de>) -> Self { |
89 | Deserializer { |
90 | inner: MapDeserializer::new(iter:PartIterator(parser)), |
91 | } |
92 | } |
93 | } |
94 | |
95 | impl<'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 | |
156 | struct PartIterator<'de>(UrlEncodedParse<'de>); |
157 | |
158 | impl<'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: Cow<'_, str>, v: Cow<'_, str>)| (Part(k), Part(v))) |
163 | } |
164 | } |
165 | |
166 | struct Part<'de>(Cow<'de, str>); |
167 | |
168 | impl<'de> IntoDeserializer<'de> for Part<'de> { |
169 | type Deserializer = Self; |
170 | |
171 | fn into_deserializer(self) -> Self::Deserializer { |
172 | self |
173 | } |
174 | } |
175 | |
176 | macro_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 | |
191 | impl<'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 | |
266 | struct ValueEnumAccess<'de>(Cow<'de, str>); |
267 | |
268 | impl<'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: ::Value = seed.deserialize(self.0.into_deserializer())?; |
280 | Ok((variant, UnitOnlyVariantAccess)) |
281 | } |
282 | } |
283 | |
284 | struct UnitOnlyVariantAccess; |
285 | |
286 | impl<'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 | } |
322 | |