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())
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_derive::Deserialize;
495
496    use super::*;
497    use crate::path::PathItem;
498
499    #[derive(Deserialize)]
500    struct MyStruct {
501        key: String,
502        value: String,
503    }
504
505    #[derive(Debug, Deserialize)]
506    struct Test1(String, u32);
507
508    #[derive(Debug, Deserialize)]
509    struct Test2 {
510        key: String,
511        value: u32,
512    }
513
514    #[derive(Debug, Deserialize, PartialEq)]
515    #[serde(rename_all = "lowercase")]
516    enum TestEnum {
517        Val1,
518        Val2,
519    }
520
521    #[derive(Debug, Deserialize)]
522    struct Test3 {
523        val: TestEnum,
524    }
525
526    #[test]
527    #[allow(clippy::let_unit_value, clippy::unit_cmp)]
528    fn test_request_extract() {
529        let mut path = Path::new("/name/user1/");
530        path.segments = vec![
531            ("key", PathItem::Static("name")),
532            ("value", PathItem::Static("user1")),
533        ];
534
535        let s: () = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
536        assert_eq!(s, ());
537
538        let s: MyStruct =
539            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
540        assert_eq!(s.key, "name");
541        assert_eq!(s.value, "user1");
542
543        let s: MyStruct = path.load().unwrap();
544        assert_eq!(s.key, "name");
545        assert_eq!(s.value, "user1");
546
547        let s: (String, String) =
548            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
549        assert_eq!(s.0, "name");
550        assert_eq!(s.1, "user1");
551
552        let s: &str = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
553        assert_eq!(s, "name");
554
555        let mut path = Path::new("/name/user1/");
556        path.segments = vec![
557            ("key", PathItem::Static("name")),
558            ("value", PathItem::Static("32")),
559        ];
560
561        let s: Test1 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
562        assert_eq!(s.0, "name");
563        assert_eq!(s.1, 32);
564
565        #[derive(Deserialize)]
566        struct T(Test1);
567        let s: T = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
568        assert_eq!((s.0).0, "name");
569        assert_eq!((s.0).1, 32);
570
571        let s: Test2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
572        assert_eq!(s.key, "name");
573        assert_eq!(s.value, 32);
574
575        let s: Result<(Test2,), _> =
576            de::Deserialize::deserialize(PathDeserializer::new(&path));
577        assert!(s.is_err());
578
579        let s: (String, u8) =
580            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
581        assert_eq!(s.0, "name");
582        assert_eq!(s.1, 32);
583
584        let s: (&str, ()) =
585            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
586        assert_eq!(s.0, "name");
587        assert_eq!(s.1, ());
588
589        let s: (&str, Option<u8>) =
590            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
591        assert_eq!(s.0, "name");
592        assert_eq!(s.1, Some(32));
593
594        let res: Vec<String> =
595            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
596        assert_eq!(res[0], "name".to_owned());
597        assert_eq!(res[1], "32".to_owned());
598
599        #[derive(Debug, Deserialize)]
600        struct S2(());
601        let s: Result<S2, de::value::Error> =
602            de::Deserialize::deserialize(PathDeserializer::new(&path));
603        assert!(s.is_ok());
604
605        let s: Result<(), de::value::Error> =
606            de::Deserialize::deserialize(PathDeserializer::new(&path));
607        assert!(s.is_ok());
608
609        let s: Result<(String, ()), de::value::Error> =
610            de::Deserialize::deserialize(PathDeserializer::new(&path));
611        assert!(s.is_ok());
612    }
613
614    #[test]
615    fn test_extract_path_single() {
616        let mut path = Path::new("/name/user1/");
617        path.segments = vec![("value", PathItem::Static("32"))];
618        let i: i8 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
619        assert_eq!(i, 32);
620
621        let i: (i8,) = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
622        assert_eq!(i, (32,));
623
624        let i: Result<(i8, i8), _> =
625            de::Deserialize::deserialize(PathDeserializer::new(&path));
626        assert!(i.is_err());
627
628        #[derive(Deserialize)]
629        struct Test(i8);
630        let i: Test = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
631        assert_eq!(i.0, 32);
632
633        path.segments.push(("value2", PathItem::Static("32")));
634        let i: Result<i8, _> = de::Deserialize::deserialize(PathDeserializer::new(&path));
635        assert!(i.is_err());
636    }
637
638    #[test]
639    fn test_extract_enum() {
640        let mut path = Path::new("/val1/");
641        path.segments = vec![("val", PathItem::Static("val1"))];
642        let i: TestEnum =
643            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
644        assert_eq!(i, TestEnum::Val1);
645
646        let mut path = Path::new("/val1/");
647        path.segments = vec![
648            ("val1", PathItem::Static("val1")),
649            ("val2", PathItem::Static("val2")),
650        ];
651        let i: (TestEnum, TestEnum) =
652            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
653        assert_eq!(i, (TestEnum::Val1, TestEnum::Val2));
654    }
655
656    #[test]
657    fn test_extract_enum_value() {
658        let mut path = Path::new("/val1/");
659        path.segments = vec![("val", PathItem::Static("val1"))];
660        let i: Test3 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
661        assert_eq!(i.val, TestEnum::Val1);
662
663        let mut path = Path::new("/val3/");
664        path.segments = vec![("val", PathItem::Static("val3"))];
665        let i: Result<Test3, de::value::Error> =
666            de::Deserialize::deserialize(PathDeserializer::new(&path));
667        assert!(i.is_err());
668        assert!(format!("{i:?}").contains("unknown variant"));
669    }
670
671    #[test]
672    fn test_extract_errors() {
673        let mut path = Path::new("/name/");
674        path.segments = vec![("value", PathItem::Static("name"))];
675
676        let s: Result<Test1, 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<Test2, 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        let s: Result<(String, String), de::value::Error> =
687            de::Deserialize::deserialize(PathDeserializer::new(&path));
688        assert!(s.is_err());
689        assert!(format!("{s:?}").contains("wrong number of parameters"));
690
691        let s: Result<u32, de::value::Error> =
692            de::Deserialize::deserialize(PathDeserializer::new(&path));
693        assert!(s.is_err());
694        assert!(format!("{s:?}").contains("can not parse"));
695
696        #[derive(Debug, Deserialize)]
697        struct S {
698            _inner: (String,),
699        }
700        let s: Result<S, de::value::Error> =
701            de::Deserialize::deserialize(PathDeserializer::new(&path));
702        assert!(s.is_err());
703        assert!(format!("{s:?}").contains("missing field `_inner`"));
704
705        let path = Path::new("");
706        let s: Result<&str, de::value::Error> =
707            de::Deserialize::deserialize(PathDeserializer::new(&path));
708        assert!(s.is_err());
709        assert!(format!("{s:?}").contains("wrong number of parameters: 0 expected 1"));
710
711        let s: Result<TestEnum, de::value::Error> =
712            de::Deserialize::deserialize(PathDeserializer::new(&path));
713        assert!(s.is_err());
714        assert!(format!("{s:?}").contains("expeceted at least one parameters"));
715    }
716}