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 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 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 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 #[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 }