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