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