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