axum/extract/path/
de.rs

1use super::{ErrorKind, PathDeserializationError};
2use crate::util::PercentDecodedStr;
3use serde::{
4    de::{self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},
5    forward_to_deserialize_any, Deserializer,
6};
7use std::{any::type_name, sync::Arc};
8
9macro_rules! unsupported_type {
10    ($trait_fn:ident) => {
11        fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
12        where
13            V: Visitor<'de>,
14        {
15            Err(PathDeserializationError::unsupported_type(type_name::<
16                V::Value,
17            >()))
18        }
19    };
20}
21
22macro_rules! parse_single_value {
23    ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {
24        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
25        where
26            V: Visitor<'de>,
27        {
28            if self.url_params.len() != 1 {
29                return Err(PathDeserializationError::wrong_number_of_parameters()
30                    .got(self.url_params.len())
31                    .expected(1));
32            }
33
34            let value = self.url_params[0].1.parse().map_err(|_| {
35                PathDeserializationError::new(ErrorKind::ParseError {
36                    value: self.url_params[0].1.as_str().to_owned(),
37                    expected_type: $ty,
38                })
39            })?;
40            visitor.$visit_fn(value)
41        }
42    };
43}
44
45pub(crate) struct PathDeserializer<'de> {
46    url_params: &'de [(Arc<str>, PercentDecodedStr)],
47}
48
49impl<'de> PathDeserializer<'de> {
50    #[inline]
51    pub(crate) fn new(url_params: &'de [(Arc<str>, PercentDecodedStr)]) -> Self {
52        PathDeserializer { url_params }
53    }
54}
55
56impl<'de> Deserializer<'de> for PathDeserializer<'de> {
57    type Error = PathDeserializationError;
58
59    unsupported_type!(deserialize_bytes);
60    unsupported_type!(deserialize_option);
61    unsupported_type!(deserialize_identifier);
62    unsupported_type!(deserialize_ignored_any);
63
64    parse_single_value!(deserialize_bool, visit_bool, "bool");
65    parse_single_value!(deserialize_i8, visit_i8, "i8");
66    parse_single_value!(deserialize_i16, visit_i16, "i16");
67    parse_single_value!(deserialize_i32, visit_i32, "i32");
68    parse_single_value!(deserialize_i64, visit_i64, "i64");
69    parse_single_value!(deserialize_i128, visit_i128, "i128");
70    parse_single_value!(deserialize_u8, visit_u8, "u8");
71    parse_single_value!(deserialize_u16, visit_u16, "u16");
72    parse_single_value!(deserialize_u32, visit_u32, "u32");
73    parse_single_value!(deserialize_u64, visit_u64, "u64");
74    parse_single_value!(deserialize_u128, visit_u128, "u128");
75    parse_single_value!(deserialize_f32, visit_f32, "f32");
76    parse_single_value!(deserialize_f64, visit_f64, "f64");
77    parse_single_value!(deserialize_string, visit_string, "String");
78    parse_single_value!(deserialize_byte_buf, visit_string, "String");
79    parse_single_value!(deserialize_char, visit_char, "char");
80
81    fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>
82    where
83        V: Visitor<'de>,
84    {
85        self.deserialize_str(v)
86    }
87
88    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
89    where
90        V: Visitor<'de>,
91    {
92        if self.url_params.len() != 1 {
93            return Err(PathDeserializationError::wrong_number_of_parameters()
94                .got(self.url_params.len())
95                .expected(1));
96        }
97        visitor.visit_borrowed_str(&self.url_params[0].1)
98    }
99
100    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
101    where
102        V: Visitor<'de>,
103    {
104        visitor.visit_unit()
105    }
106
107    fn deserialize_unit_struct<V>(
108        self,
109        _name: &'static str,
110        visitor: V,
111    ) -> Result<V::Value, Self::Error>
112    where
113        V: Visitor<'de>,
114    {
115        visitor.visit_unit()
116    }
117
118    fn deserialize_newtype_struct<V>(
119        self,
120        _name: &'static str,
121        visitor: V,
122    ) -> Result<V::Value, Self::Error>
123    where
124        V: Visitor<'de>,
125    {
126        visitor.visit_newtype_struct(self)
127    }
128
129    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
130    where
131        V: Visitor<'de>,
132    {
133        visitor.visit_seq(SeqDeserializer {
134            params: self.url_params,
135            idx: 0,
136        })
137    }
138
139    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
140    where
141        V: Visitor<'de>,
142    {
143        if self.url_params.len() < len {
144            return Err(PathDeserializationError::wrong_number_of_parameters()
145                .got(self.url_params.len())
146                .expected(len));
147        }
148        visitor.visit_seq(SeqDeserializer {
149            params: self.url_params,
150            idx: 0,
151        })
152    }
153
154    fn deserialize_tuple_struct<V>(
155        self,
156        _name: &'static str,
157        len: usize,
158        visitor: V,
159    ) -> Result<V::Value, Self::Error>
160    where
161        V: Visitor<'de>,
162    {
163        if self.url_params.len() < len {
164            return Err(PathDeserializationError::wrong_number_of_parameters()
165                .got(self.url_params.len())
166                .expected(len));
167        }
168        visitor.visit_seq(SeqDeserializer {
169            params: self.url_params,
170            idx: 0,
171        })
172    }
173
174    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
175    where
176        V: Visitor<'de>,
177    {
178        visitor.visit_map(MapDeserializer {
179            params: self.url_params,
180            value: None,
181            key: None,
182        })
183    }
184
185    fn deserialize_struct<V>(
186        self,
187        _name: &'static str,
188        _fields: &'static [&'static str],
189        visitor: V,
190    ) -> Result<V::Value, Self::Error>
191    where
192        V: Visitor<'de>,
193    {
194        self.deserialize_map(visitor)
195    }
196
197    fn deserialize_enum<V>(
198        self,
199        _name: &'static str,
200        _variants: &'static [&'static str],
201        visitor: V,
202    ) -> Result<V::Value, Self::Error>
203    where
204        V: Visitor<'de>,
205    {
206        if self.url_params.len() != 1 {
207            return Err(PathDeserializationError::wrong_number_of_parameters()
208                .got(self.url_params.len())
209                .expected(1));
210        }
211
212        visitor.visit_enum(EnumDeserializer {
213            value: self.url_params[0].1.clone().into_inner(),
214        })
215    }
216}
217
218struct MapDeserializer<'de> {
219    params: &'de [(Arc<str>, PercentDecodedStr)],
220    key: Option<KeyOrIdx>,
221    value: Option<&'de PercentDecodedStr>,
222}
223
224impl<'de> MapAccess<'de> for MapDeserializer<'de> {
225    type Error = PathDeserializationError;
226
227    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
228    where
229        K: DeserializeSeed<'de>,
230    {
231        match self.params.split_first() {
232            Some(((key, value), tail)) => {
233                self.value = Some(value);
234                self.params = tail;
235                self.key = Some(KeyOrIdx::Key(key.clone()));
236                seed.deserialize(KeyDeserializer {
237                    key: Arc::clone(key),
238                })
239                .map(Some)
240            }
241            None => Ok(None),
242        }
243    }
244
245    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
246    where
247        V: DeserializeSeed<'de>,
248    {
249        match self.value.take() {
250            Some(value) => seed.deserialize(ValueDeserializer {
251                key: self.key.take(),
252                value,
253            }),
254            None => Err(PathDeserializationError::custom("value is missing")),
255        }
256    }
257}
258
259struct KeyDeserializer {
260    key: Arc<str>,
261}
262
263macro_rules! parse_key {
264    ($trait_fn:ident) => {
265        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
266        where
267            V: Visitor<'de>,
268        {
269            visitor.visit_str(&self.key)
270        }
271    };
272}
273
274impl<'de> Deserializer<'de> for KeyDeserializer {
275    type Error = PathDeserializationError;
276
277    parse_key!(deserialize_identifier);
278    parse_key!(deserialize_str);
279    parse_key!(deserialize_string);
280
281    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
282    where
283        V: Visitor<'de>,
284    {
285        Err(PathDeserializationError::custom("Unexpected key type"))
286    }
287
288    forward_to_deserialize_any! {
289        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char bytes
290        byte_buf option unit unit_struct seq tuple
291        tuple_struct map newtype_struct struct enum ignored_any
292    }
293}
294
295macro_rules! parse_value {
296    ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {
297        fn $trait_fn<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
298        where
299            V: Visitor<'de>,
300        {
301            let v = self.value.parse().map_err(|_| {
302                if let Some(key) = self.key.take() {
303                    let kind = match key {
304                        KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey {
305                            key: key.to_string(),
306                            value: self.value.as_str().to_owned(),
307                            expected_type: $ty,
308                        },
309                        KeyOrIdx::Idx { idx: index, key: _ } => ErrorKind::ParseErrorAtIndex {
310                            index,
311                            value: self.value.as_str().to_owned(),
312                            expected_type: $ty,
313                        },
314                    };
315                    PathDeserializationError::new(kind)
316                } else {
317                    PathDeserializationError::new(ErrorKind::ParseError {
318                        value: self.value.as_str().to_owned(),
319                        expected_type: $ty,
320                    })
321                }
322            })?;
323            visitor.$visit_fn(v)
324        }
325    };
326}
327
328#[derive(Debug)]
329struct ValueDeserializer<'de> {
330    key: Option<KeyOrIdx>,
331    value: &'de PercentDecodedStr,
332}
333
334impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
335    type Error = PathDeserializationError;
336
337    unsupported_type!(deserialize_map);
338    unsupported_type!(deserialize_identifier);
339
340    parse_value!(deserialize_bool, visit_bool, "bool");
341    parse_value!(deserialize_i8, visit_i8, "i8");
342    parse_value!(deserialize_i16, visit_i16, "i16");
343    parse_value!(deserialize_i32, visit_i32, "i32");
344    parse_value!(deserialize_i64, visit_i64, "i64");
345    parse_value!(deserialize_i128, visit_i128, "i128");
346    parse_value!(deserialize_u8, visit_u8, "u8");
347    parse_value!(deserialize_u16, visit_u16, "u16");
348    parse_value!(deserialize_u32, visit_u32, "u32");
349    parse_value!(deserialize_u64, visit_u64, "u64");
350    parse_value!(deserialize_u128, visit_u128, "u128");
351    parse_value!(deserialize_f32, visit_f32, "f32");
352    parse_value!(deserialize_f64, visit_f64, "f64");
353    parse_value!(deserialize_string, visit_string, "String");
354    parse_value!(deserialize_byte_buf, visit_string, "String");
355    parse_value!(deserialize_char, visit_char, "char");
356
357    fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>
358    where
359        V: Visitor<'de>,
360    {
361        self.deserialize_str(v)
362    }
363
364    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
365    where
366        V: Visitor<'de>,
367    {
368        visitor.visit_borrowed_str(self.value)
369    }
370
371    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
372    where
373        V: Visitor<'de>,
374    {
375        visitor.visit_borrowed_bytes(self.value.as_bytes())
376    }
377
378    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
379    where
380        V: Visitor<'de>,
381    {
382        visitor.visit_some(self)
383    }
384
385    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
386    where
387        V: Visitor<'de>,
388    {
389        visitor.visit_unit()
390    }
391
392    fn deserialize_unit_struct<V>(
393        self,
394        _name: &'static str,
395        visitor: V,
396    ) -> Result<V::Value, Self::Error>
397    where
398        V: Visitor<'de>,
399    {
400        visitor.visit_unit()
401    }
402
403    fn deserialize_newtype_struct<V>(
404        self,
405        _name: &'static str,
406        visitor: V,
407    ) -> Result<V::Value, Self::Error>
408    where
409        V: Visitor<'de>,
410    {
411        visitor.visit_newtype_struct(self)
412    }
413
414    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
415    where
416        V: Visitor<'de>,
417    {
418        struct PairDeserializer<'de> {
419            key: Option<KeyOrIdx>,
420            value: Option<&'de PercentDecodedStr>,
421        }
422
423        impl<'de> SeqAccess<'de> for PairDeserializer<'de> {
424            type Error = PathDeserializationError;
425
426            fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
427            where
428                T: DeserializeSeed<'de>,
429            {
430                match self.key.take() {
431                    Some(KeyOrIdx::Idx { idx: _, key }) => {
432                        return seed.deserialize(KeyDeserializer { key }).map(Some);
433                    }
434                    // `KeyOrIdx::Key` is only used when deserializing maps so `deserialize_seq`
435                    // wouldn't be called for that
436                    Some(KeyOrIdx::Key(_)) => unreachable!(),
437                    None => {}
438                };
439
440                self.value
441                    .take()
442                    .map(|value| seed.deserialize(ValueDeserializer { key: None, value }))
443                    .transpose()
444            }
445        }
446
447        if len == 2 {
448            match self.key {
449                Some(key) => visitor.visit_seq(PairDeserializer {
450                    key: Some(key),
451                    value: Some(self.value),
452                }),
453                // `self.key` is only `None` when deserializing maps so `deserialize_seq`
454                // wouldn't be called for that
455                None => unreachable!(),
456            }
457        } else {
458            Err(PathDeserializationError::unsupported_type(type_name::<
459                V::Value,
460            >()))
461        }
462    }
463
464    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
465    where
466        V: Visitor<'de>,
467    {
468        Err(PathDeserializationError::unsupported_type(type_name::<
469            V::Value,
470        >()))
471    }
472
473    fn deserialize_tuple_struct<V>(
474        self,
475        _name: &'static str,
476        _len: usize,
477        _visitor: V,
478    ) -> Result<V::Value, Self::Error>
479    where
480        V: Visitor<'de>,
481    {
482        Err(PathDeserializationError::unsupported_type(type_name::<
483            V::Value,
484        >()))
485    }
486
487    fn deserialize_struct<V>(
488        self,
489        _name: &'static str,
490        _fields: &'static [&'static str],
491        _visitor: V,
492    ) -> Result<V::Value, Self::Error>
493    where
494        V: Visitor<'de>,
495    {
496        Err(PathDeserializationError::unsupported_type(type_name::<
497            V::Value,
498        >()))
499    }
500
501    fn deserialize_enum<V>(
502        self,
503        _name: &'static str,
504        _variants: &'static [&'static str],
505        visitor: V,
506    ) -> Result<V::Value, Self::Error>
507    where
508        V: Visitor<'de>,
509    {
510        visitor.visit_enum(EnumDeserializer {
511            value: self.value.clone().into_inner(),
512        })
513    }
514
515    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
516    where
517        V: Visitor<'de>,
518    {
519        visitor.visit_unit()
520    }
521}
522
523struct EnumDeserializer {
524    value: Arc<str>,
525}
526
527impl<'de> EnumAccess<'de> for EnumDeserializer {
528    type Error = PathDeserializationError;
529    type Variant = UnitVariant;
530
531    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
532    where
533        V: de::DeserializeSeed<'de>,
534    {
535        Ok((
536            seed.deserialize(KeyDeserializer { key: self.value })?,
537            UnitVariant,
538        ))
539    }
540}
541
542struct UnitVariant;
543
544impl<'de> VariantAccess<'de> for UnitVariant {
545    type Error = PathDeserializationError;
546
547    fn unit_variant(self) -> Result<(), Self::Error> {
548        Ok(())
549    }
550
551    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
552    where
553        T: DeserializeSeed<'de>,
554    {
555        Err(PathDeserializationError::unsupported_type(
556            "newtype enum variant",
557        ))
558    }
559
560    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
561    where
562        V: Visitor<'de>,
563    {
564        Err(PathDeserializationError::unsupported_type(
565            "tuple enum variant",
566        ))
567    }
568
569    fn struct_variant<V>(
570        self,
571        _fields: &'static [&'static str],
572        _visitor: V,
573    ) -> Result<V::Value, Self::Error>
574    where
575        V: Visitor<'de>,
576    {
577        Err(PathDeserializationError::unsupported_type(
578            "struct enum variant",
579        ))
580    }
581}
582
583struct SeqDeserializer<'de> {
584    params: &'de [(Arc<str>, PercentDecodedStr)],
585    idx: usize,
586}
587
588impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
589    type Error = PathDeserializationError;
590
591    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
592    where
593        T: DeserializeSeed<'de>,
594    {
595        match self.params.split_first() {
596            Some(((key, value), tail)) => {
597                self.params = tail;
598                let idx = self.idx;
599                self.idx += 1;
600                Ok(Some(seed.deserialize(ValueDeserializer {
601                    key: Some(KeyOrIdx::Idx {
602                        idx,
603                        key: key.clone(),
604                    }),
605                    value,
606                })?))
607            }
608            None => Ok(None),
609        }
610    }
611}
612
613#[derive(Debug, Clone)]
614enum KeyOrIdx {
615    Key(Arc<str>),
616    Idx { idx: usize, key: Arc<str> },
617}
618
619#[cfg(test)]
620mod tests {
621    use super::*;
622    use serde::Deserialize;
623    use std::collections::HashMap;
624
625    #[derive(Debug, Deserialize, Eq, PartialEq)]
626    enum MyEnum {
627        A,
628        B,
629        #[serde(rename = "c")]
630        C,
631    }
632
633    #[derive(Debug, Deserialize, Eq, PartialEq)]
634    struct Struct {
635        c: String,
636        b: bool,
637        a: i32,
638    }
639
640    fn create_url_params<I, K, V>(values: I) -> Vec<(Arc<str>, PercentDecodedStr)>
641    where
642        I: IntoIterator<Item = (K, V)>,
643        K: AsRef<str>,
644        V: AsRef<str>,
645    {
646        values
647            .into_iter()
648            .map(|(k, v)| (Arc::from(k.as_ref()), PercentDecodedStr::new(v).unwrap()))
649            .collect()
650    }
651
652    macro_rules! check_single_value {
653        ($ty:ty, $value_str:literal, $value:expr) => {
654            #[allow(clippy::bool_assert_comparison)]
655            {
656                let url_params = create_url_params(vec![("value", $value_str)]);
657                let deserializer = PathDeserializer::new(&url_params);
658                assert_eq!(<$ty>::deserialize(deserializer).unwrap(), $value);
659            }
660        };
661    }
662
663    #[test]
664    fn test_parse_single_value() {
665        check_single_value!(bool, "true", true);
666        check_single_value!(bool, "false", false);
667        check_single_value!(i8, "-123", -123);
668        check_single_value!(i16, "-123", -123);
669        check_single_value!(i32, "-123", -123);
670        check_single_value!(i64, "-123", -123);
671        check_single_value!(i128, "123", 123);
672        check_single_value!(u8, "123", 123);
673        check_single_value!(u16, "123", 123);
674        check_single_value!(u32, "123", 123);
675        check_single_value!(u64, "123", 123);
676        check_single_value!(u128, "123", 123);
677        check_single_value!(f32, "123", 123.0);
678        check_single_value!(f64, "123", 123.0);
679        check_single_value!(String, "abc", "abc");
680        check_single_value!(String, "one%20two", "one two");
681        check_single_value!(&str, "abc", "abc");
682        check_single_value!(&str, "one%20two", "one two");
683        check_single_value!(char, "a", 'a');
684
685        let url_params = create_url_params(vec![("a", "B")]);
686        assert_eq!(
687            MyEnum::deserialize(PathDeserializer::new(&url_params)).unwrap(),
688            MyEnum::B
689        );
690
691        let url_params = create_url_params(vec![("a", "1"), ("b", "2")]);
692        let error_kind = i32::deserialize(PathDeserializer::new(&url_params))
693            .unwrap_err()
694            .kind;
695        assert!(matches!(
696            error_kind,
697            ErrorKind::WrongNumberOfParameters {
698                expected: 1,
699                got: 2
700            }
701        ));
702    }
703
704    #[test]
705    fn test_parse_seq() {
706        let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
707        assert_eq!(
708            <(i32, bool, String)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
709            (1, true, "abc".to_owned())
710        );
711
712        #[derive(Debug, Deserialize, Eq, PartialEq)]
713        struct TupleStruct(i32, bool, String);
714        assert_eq!(
715            TupleStruct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
716            TupleStruct(1, true, "abc".to_owned())
717        );
718
719        let url_params = create_url_params(vec![("a", "1"), ("b", "2"), ("c", "3")]);
720        assert_eq!(
721            <Vec<i32>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
722            vec![1, 2, 3]
723        );
724
725        let url_params = create_url_params(vec![("a", "c"), ("a", "B")]);
726        assert_eq!(
727            <Vec<MyEnum>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
728            vec![MyEnum::C, MyEnum::B]
729        );
730    }
731
732    #[test]
733    fn test_parse_seq_tuple_string_string() {
734        let url_params = create_url_params(vec![("a", "foo"), ("b", "bar")]);
735        assert_eq!(
736            <Vec<(String, String)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
737            vec![
738                ("a".to_owned(), "foo".to_owned()),
739                ("b".to_owned(), "bar".to_owned())
740            ]
741        );
742    }
743
744    #[test]
745    fn test_parse_seq_tuple_string_parse() {
746        let url_params = create_url_params(vec![("a", "1"), ("b", "2")]);
747        assert_eq!(
748            <Vec<(String, u32)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
749            vec![("a".to_owned(), 1), ("b".to_owned(), 2)]
750        );
751    }
752
753    #[test]
754    fn test_parse_struct() {
755        let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
756        assert_eq!(
757            Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
758            Struct {
759                c: "abc".to_owned(),
760                b: true,
761                a: 1,
762            }
763        );
764    }
765
766    #[test]
767    fn test_parse_struct_ignoring_additional_fields() {
768        let url_params = create_url_params(vec![
769            ("a", "1"),
770            ("b", "true"),
771            ("c", "abc"),
772            ("d", "false"),
773        ]);
774        assert_eq!(
775            Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
776            Struct {
777                c: "abc".to_owned(),
778                b: true,
779                a: 1,
780            }
781        );
782    }
783
784    #[test]
785    fn test_parse_tuple_ignoring_additional_fields() {
786        let url_params = create_url_params(vec![
787            ("a", "abc"),
788            ("b", "true"),
789            ("c", "1"),
790            ("d", "false"),
791        ]);
792        assert_eq!(
793            <(&str, bool, u32)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
794            ("abc", true, 1)
795        );
796    }
797
798    #[test]
799    fn test_parse_map() {
800        let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
801        assert_eq!(
802            <HashMap<String, String>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
803            [("a", "1"), ("b", "true"), ("c", "abc")]
804                .iter()
805                .map(|(key, value)| ((*key).to_owned(), (*value).to_owned()))
806                .collect()
807        );
808    }
809
810    macro_rules! test_parse_error {
811        (
812            $params:expr,
813            $ty:ty,
814            $expected_error_kind:expr $(,)?
815        ) => {
816            let url_params = create_url_params($params);
817            let actual_error_kind = <$ty>::deserialize(PathDeserializer::new(&url_params))
818                .unwrap_err()
819                .kind;
820            assert_eq!(actual_error_kind, $expected_error_kind);
821        };
822    }
823
824    #[test]
825    fn test_wrong_number_of_parameters_error() {
826        test_parse_error!(
827            vec![("a", "1")],
828            (u32, u32),
829            ErrorKind::WrongNumberOfParameters {
830                got: 1,
831                expected: 2,
832            }
833        );
834    }
835
836    #[test]
837    fn test_parse_error_at_key_error() {
838        #[derive(Debug, Deserialize)]
839        #[allow(dead_code)]
840        struct Params {
841            a: u32,
842        }
843        test_parse_error!(
844            vec![("a", "false")],
845            Params,
846            ErrorKind::ParseErrorAtKey {
847                key: "a".to_owned(),
848                value: "false".to_owned(),
849                expected_type: "u32",
850            }
851        );
852    }
853
854    #[test]
855    fn test_parse_error_at_key_error_multiple() {
856        #[derive(Debug, Deserialize)]
857        #[allow(dead_code)]
858        struct Params {
859            a: u32,
860            b: u32,
861        }
862        test_parse_error!(
863            vec![("a", "false")],
864            Params,
865            ErrorKind::ParseErrorAtKey {
866                key: "a".to_owned(),
867                value: "false".to_owned(),
868                expected_type: "u32",
869            }
870        );
871    }
872
873    #[test]
874    fn test_parse_error_at_index_error() {
875        test_parse_error!(
876            vec![("a", "false"), ("b", "true")],
877            (bool, u32),
878            ErrorKind::ParseErrorAtIndex {
879                index: 1,
880                value: "true".to_owned(),
881                expected_type: "u32",
882            }
883        );
884    }
885
886    #[test]
887    fn test_parse_error_error() {
888        test_parse_error!(
889            vec![("a", "false")],
890            u32,
891            ErrorKind::ParseError {
892                value: "false".to_owned(),
893                expected_type: "u32",
894            }
895        );
896    }
897
898    #[test]
899    fn test_unsupported_type_error_nested_data_structure() {
900        test_parse_error!(
901            vec![("a", "false")],
902            Vec<Vec<u32>>,
903            ErrorKind::UnsupportedType {
904                name: "alloc::vec::Vec<u32>",
905            }
906        );
907    }
908
909    #[test]
910    fn test_parse_seq_tuple_unsupported_key_type() {
911        test_parse_error!(
912            vec![("a", "false")],
913            Vec<(u32, String)>,
914            ErrorKind::Message("Unexpected key type".to_owned())
915        );
916    }
917
918    #[test]
919    fn test_parse_seq_wrong_tuple_length() {
920        test_parse_error!(
921            vec![("a", "false")],
922            Vec<(String, String, String)>,
923            ErrorKind::UnsupportedType {
924                name: "(alloc::string::String, alloc::string::String, alloc::string::String)",
925            }
926        );
927    }
928
929    #[test]
930    fn test_parse_seq_seq() {
931        test_parse_error!(
932            vec![("a", "false")],
933            Vec<Vec<String>>,
934            ErrorKind::UnsupportedType {
935                name: "alloc::vec::Vec<alloc::string::String>",
936            }
937        );
938    }
939}