ntex_router/
de.rs

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