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 }