actix_router/
de.rs

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