Skip to main content

ntex_router/
de.rs

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