1use super::{ErrorKind, PathDeserializationError};
2use crate::util::PercentDecodedStr;
3use serde::{
4 de::{self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},
5 forward_to_deserialize_any, Deserializer,
6};
7use std::{any::type_name, sync::Arc};
8
9macro_rules! unsupported_type {
10 ($trait_fn:ident) => {
11 fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
12 where
13 V: Visitor<'de>,
14 {
15 Err(PathDeserializationError::unsupported_type(type_name::<
16 V::Value,
17 >()))
18 }
19 };
20}
21
22macro_rules! parse_single_value {
23 ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {
24 fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
25 where
26 V: Visitor<'de>,
27 {
28 if self.url_params.len() != 1 {
29 return Err(PathDeserializationError::wrong_number_of_parameters()
30 .got(self.url_params.len())
31 .expected(1));
32 }
33
34 let value = self.url_params[0].1.parse().map_err(|_| {
35 PathDeserializationError::new(ErrorKind::ParseError {
36 value: self.url_params[0].1.as_str().to_owned(),
37 expected_type: $ty,
38 })
39 })?;
40 visitor.$visit_fn(value)
41 }
42 };
43}
44
45pub(crate) struct PathDeserializer<'de> {
46 url_params: &'de [(Arc<str>, PercentDecodedStr)],
47}
48
49impl<'de> PathDeserializer<'de> {
50 #[inline]
51 pub(crate) fn new(url_params: &'de [(Arc<str>, PercentDecodedStr)]) -> Self {
52 PathDeserializer { url_params }
53 }
54}
55
56impl<'de> Deserializer<'de> for PathDeserializer<'de> {
57 type Error = PathDeserializationError;
58
59 unsupported_type!(deserialize_bytes);
60 unsupported_type!(deserialize_option);
61 unsupported_type!(deserialize_identifier);
62 unsupported_type!(deserialize_ignored_any);
63
64 parse_single_value!(deserialize_bool, visit_bool, "bool");
65 parse_single_value!(deserialize_i8, visit_i8, "i8");
66 parse_single_value!(deserialize_i16, visit_i16, "i16");
67 parse_single_value!(deserialize_i32, visit_i32, "i32");
68 parse_single_value!(deserialize_i64, visit_i64, "i64");
69 parse_single_value!(deserialize_i128, visit_i128, "i128");
70 parse_single_value!(deserialize_u8, visit_u8, "u8");
71 parse_single_value!(deserialize_u16, visit_u16, "u16");
72 parse_single_value!(deserialize_u32, visit_u32, "u32");
73 parse_single_value!(deserialize_u64, visit_u64, "u64");
74 parse_single_value!(deserialize_u128, visit_u128, "u128");
75 parse_single_value!(deserialize_f32, visit_f32, "f32");
76 parse_single_value!(deserialize_f64, visit_f64, "f64");
77 parse_single_value!(deserialize_string, visit_string, "String");
78 parse_single_value!(deserialize_byte_buf, visit_string, "String");
79 parse_single_value!(deserialize_char, visit_char, "char");
80
81 fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>
82 where
83 V: Visitor<'de>,
84 {
85 self.deserialize_str(v)
86 }
87
88 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
89 where
90 V: Visitor<'de>,
91 {
92 if self.url_params.len() != 1 {
93 return Err(PathDeserializationError::wrong_number_of_parameters()
94 .got(self.url_params.len())
95 .expected(1));
96 }
97 visitor.visit_borrowed_str(&self.url_params[0].1)
98 }
99
100 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
101 where
102 V: Visitor<'de>,
103 {
104 visitor.visit_unit()
105 }
106
107 fn deserialize_unit_struct<V>(
108 self,
109 _name: &'static str,
110 visitor: V,
111 ) -> Result<V::Value, Self::Error>
112 where
113 V: Visitor<'de>,
114 {
115 visitor.visit_unit()
116 }
117
118 fn deserialize_newtype_struct<V>(
119 self,
120 _name: &'static str,
121 visitor: V,
122 ) -> Result<V::Value, Self::Error>
123 where
124 V: Visitor<'de>,
125 {
126 visitor.visit_newtype_struct(self)
127 }
128
129 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
130 where
131 V: Visitor<'de>,
132 {
133 visitor.visit_seq(SeqDeserializer {
134 params: self.url_params,
135 idx: 0,
136 })
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.url_params.len() < len {
144 return Err(PathDeserializationError::wrong_number_of_parameters()
145 .got(self.url_params.len())
146 .expected(len));
147 }
148 visitor.visit_seq(SeqDeserializer {
149 params: self.url_params,
150 idx: 0,
151 })
152 }
153
154 fn deserialize_tuple_struct<V>(
155 self,
156 _name: &'static str,
157 len: usize,
158 visitor: V,
159 ) -> Result<V::Value, Self::Error>
160 where
161 V: Visitor<'de>,
162 {
163 if self.url_params.len() < len {
164 return Err(PathDeserializationError::wrong_number_of_parameters()
165 .got(self.url_params.len())
166 .expected(len));
167 }
168 visitor.visit_seq(SeqDeserializer {
169 params: self.url_params,
170 idx: 0,
171 })
172 }
173
174 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
175 where
176 V: Visitor<'de>,
177 {
178 visitor.visit_map(MapDeserializer {
179 params: self.url_params,
180 value: None,
181 key: None,
182 })
183 }
184
185 fn deserialize_struct<V>(
186 self,
187 _name: &'static str,
188 _fields: &'static [&'static str],
189 visitor: V,
190 ) -> Result<V::Value, Self::Error>
191 where
192 V: Visitor<'de>,
193 {
194 self.deserialize_map(visitor)
195 }
196
197 fn deserialize_enum<V>(
198 self,
199 _name: &'static str,
200 _variants: &'static [&'static str],
201 visitor: V,
202 ) -> Result<V::Value, Self::Error>
203 where
204 V: Visitor<'de>,
205 {
206 if self.url_params.len() != 1 {
207 return Err(PathDeserializationError::wrong_number_of_parameters()
208 .got(self.url_params.len())
209 .expected(1));
210 }
211
212 visitor.visit_enum(EnumDeserializer {
213 value: &self.url_params[0].1,
214 })
215 }
216}
217
218struct MapDeserializer<'de> {
219 params: &'de [(Arc<str>, PercentDecodedStr)],
220 key: Option<KeyOrIdx<'de>>,
221 value: Option<&'de PercentDecodedStr>,
222}
223
224impl<'de> MapAccess<'de> for MapDeserializer<'de> {
225 type Error = PathDeserializationError;
226
227 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
228 where
229 K: DeserializeSeed<'de>,
230 {
231 match self.params.split_first() {
232 Some(((key, value), tail)) => {
233 self.value = Some(value);
234 self.params = tail;
235 self.key = Some(KeyOrIdx::Key(key));
236 seed.deserialize(KeyDeserializer { key }).map(Some)
237 }
238 None => Ok(None),
239 }
240 }
241
242 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
243 where
244 V: DeserializeSeed<'de>,
245 {
246 match self.value.take() {
247 Some(value) => seed.deserialize(ValueDeserializer {
248 key: self.key.take(),
249 value,
250 }),
251 None => Err(PathDeserializationError::custom("value is missing")),
252 }
253 }
254}
255
256struct KeyDeserializer<'de> {
257 key: &'de str,
258}
259
260macro_rules! parse_key {
261 ($trait_fn:ident) => {
262 fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
263 where
264 V: Visitor<'de>,
265 {
266 visitor.visit_str(&self.key)
267 }
268 };
269}
270
271impl<'de> Deserializer<'de> for KeyDeserializer<'de> {
272 type Error = PathDeserializationError;
273
274 parse_key!(deserialize_identifier);
275 parse_key!(deserialize_str);
276 parse_key!(deserialize_string);
277
278 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
279 where
280 V: Visitor<'de>,
281 {
282 Err(PathDeserializationError::custom("Unexpected key type"))
283 }
284
285 forward_to_deserialize_any! {
286 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char bytes
287 byte_buf option unit unit_struct seq tuple
288 tuple_struct map newtype_struct struct enum ignored_any
289 }
290}
291
292macro_rules! parse_value {
293 ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {
294 fn $trait_fn<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
295 where
296 V: Visitor<'de>,
297 {
298 let v = self.value.parse().map_err(|_| {
299 if let Some(key) = self.key.take() {
300 let kind = match key {
301 KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey {
302 key: key.to_owned(),
303 value: self.value.as_str().to_owned(),
304 expected_type: $ty,
305 },
306 KeyOrIdx::Idx { idx: index, key: _ } => ErrorKind::ParseErrorAtIndex {
307 index,
308 value: self.value.as_str().to_owned(),
309 expected_type: $ty,
310 },
311 };
312 PathDeserializationError::new(kind)
313 } else {
314 PathDeserializationError::new(ErrorKind::ParseError {
315 value: self.value.as_str().to_owned(),
316 expected_type: $ty,
317 })
318 }
319 })?;
320 visitor.$visit_fn(v)
321 }
322 };
323}
324
325#[derive(Debug)]
326struct ValueDeserializer<'de> {
327 key: Option<KeyOrIdx<'de>>,
328 value: &'de PercentDecodedStr,
329}
330
331impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
332 type Error = PathDeserializationError;
333
334 unsupported_type!(deserialize_map);
335 unsupported_type!(deserialize_identifier);
336
337 parse_value!(deserialize_bool, visit_bool, "bool");
338 parse_value!(deserialize_i8, visit_i8, "i8");
339 parse_value!(deserialize_i16, visit_i16, "i16");
340 parse_value!(deserialize_i32, visit_i32, "i32");
341 parse_value!(deserialize_i64, visit_i64, "i64");
342 parse_value!(deserialize_i128, visit_i128, "i128");
343 parse_value!(deserialize_u8, visit_u8, "u8");
344 parse_value!(deserialize_u16, visit_u16, "u16");
345 parse_value!(deserialize_u32, visit_u32, "u32");
346 parse_value!(deserialize_u64, visit_u64, "u64");
347 parse_value!(deserialize_u128, visit_u128, "u128");
348 parse_value!(deserialize_f32, visit_f32, "f32");
349 parse_value!(deserialize_f64, visit_f64, "f64");
350 parse_value!(deserialize_string, visit_string, "String");
351 parse_value!(deserialize_byte_buf, visit_string, "String");
352 parse_value!(deserialize_char, visit_char, "char");
353
354 fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>
355 where
356 V: Visitor<'de>,
357 {
358 self.deserialize_str(v)
359 }
360
361 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
362 where
363 V: Visitor<'de>,
364 {
365 visitor.visit_borrowed_str(self.value)
366 }
367
368 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
369 where
370 V: Visitor<'de>,
371 {
372 visitor.visit_borrowed_bytes(self.value.as_bytes())
373 }
374
375 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
376 where
377 V: Visitor<'de>,
378 {
379 visitor.visit_some(self)
380 }
381
382 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
383 where
384 V: Visitor<'de>,
385 {
386 visitor.visit_unit()
387 }
388
389 fn deserialize_unit_struct<V>(
390 self,
391 _name: &'static str,
392 visitor: V,
393 ) -> Result<V::Value, Self::Error>
394 where
395 V: Visitor<'de>,
396 {
397 visitor.visit_unit()
398 }
399
400 fn deserialize_newtype_struct<V>(
401 self,
402 _name: &'static str,
403 visitor: V,
404 ) -> Result<V::Value, Self::Error>
405 where
406 V: Visitor<'de>,
407 {
408 visitor.visit_newtype_struct(self)
409 }
410
411 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
412 where
413 V: Visitor<'de>,
414 {
415 struct PairDeserializer<'de> {
416 key: Option<KeyOrIdx<'de>>,
417 value: Option<&'de PercentDecodedStr>,
418 }
419
420 impl<'de> SeqAccess<'de> for PairDeserializer<'de> {
421 type Error = PathDeserializationError;
422
423 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
424 where
425 T: DeserializeSeed<'de>,
426 {
427 match self.key.take() {
428 Some(KeyOrIdx::Idx { idx: _, key }) => {
429 return seed.deserialize(KeyDeserializer { key }).map(Some);
430 }
431 Some(KeyOrIdx::Key(_)) => unreachable!(),
434 None => {}
435 };
436
437 self.value
438 .take()
439 .map(|value| seed.deserialize(ValueDeserializer { key: None, value }))
440 .transpose()
441 }
442 }
443
444 if len == 2 {
445 match self.key {
446 Some(key) => visitor.visit_seq(PairDeserializer {
447 key: Some(key),
448 value: Some(self.value),
449 }),
450 None => unreachable!(),
453 }
454 } else {
455 Err(PathDeserializationError::unsupported_type(type_name::<
456 V::Value,
457 >()))
458 }
459 }
460
461 fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
462 where
463 V: Visitor<'de>,
464 {
465 Err(PathDeserializationError::unsupported_type(type_name::<
466 V::Value,
467 >()))
468 }
469
470 fn deserialize_tuple_struct<V>(
471 self,
472 _name: &'static str,
473 _len: usize,
474 _visitor: V,
475 ) -> Result<V::Value, Self::Error>
476 where
477 V: Visitor<'de>,
478 {
479 Err(PathDeserializationError::unsupported_type(type_name::<
480 V::Value,
481 >()))
482 }
483
484 fn deserialize_struct<V>(
485 self,
486 _name: &'static str,
487 _fields: &'static [&'static str],
488 _visitor: V,
489 ) -> Result<V::Value, Self::Error>
490 where
491 V: Visitor<'de>,
492 {
493 Err(PathDeserializationError::unsupported_type(type_name::<
494 V::Value,
495 >()))
496 }
497
498 fn deserialize_enum<V>(
499 self,
500 _name: &'static str,
501 _variants: &'static [&'static str],
502 visitor: V,
503 ) -> Result<V::Value, Self::Error>
504 where
505 V: Visitor<'de>,
506 {
507 visitor.visit_enum(EnumDeserializer { value: self.value })
508 }
509
510 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
511 where
512 V: Visitor<'de>,
513 {
514 visitor.visit_unit()
515 }
516}
517
518struct EnumDeserializer<'de> {
519 value: &'de str,
520}
521
522impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
523 type Error = PathDeserializationError;
524 type Variant = UnitVariant;
525
526 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
527 where
528 V: de::DeserializeSeed<'de>,
529 {
530 Ok((
531 seed.deserialize(KeyDeserializer { key: self.value })?,
532 UnitVariant,
533 ))
534 }
535}
536
537struct UnitVariant;
538
539impl<'de> VariantAccess<'de> for UnitVariant {
540 type Error = PathDeserializationError;
541
542 fn unit_variant(self) -> Result<(), Self::Error> {
543 Ok(())
544 }
545
546 fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
547 where
548 T: DeserializeSeed<'de>,
549 {
550 Err(PathDeserializationError::unsupported_type(
551 "newtype enum variant",
552 ))
553 }
554
555 fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
556 where
557 V: Visitor<'de>,
558 {
559 Err(PathDeserializationError::unsupported_type(
560 "tuple enum variant",
561 ))
562 }
563
564 fn struct_variant<V>(
565 self,
566 _fields: &'static [&'static str],
567 _visitor: V,
568 ) -> Result<V::Value, Self::Error>
569 where
570 V: Visitor<'de>,
571 {
572 Err(PathDeserializationError::unsupported_type(
573 "struct enum variant",
574 ))
575 }
576}
577
578struct SeqDeserializer<'de> {
579 params: &'de [(Arc<str>, PercentDecodedStr)],
580 idx: usize,
581}
582
583impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
584 type Error = PathDeserializationError;
585
586 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
587 where
588 T: DeserializeSeed<'de>,
589 {
590 match self.params.split_first() {
591 Some(((key, value), tail)) => {
592 self.params = tail;
593 let idx = self.idx;
594 self.idx += 1;
595 Ok(Some(seed.deserialize(ValueDeserializer {
596 key: Some(KeyOrIdx::Idx { idx, key }),
597 value,
598 })?))
599 }
600 None => Ok(None),
601 }
602 }
603}
604
605#[derive(Debug, Clone)]
606enum KeyOrIdx<'de> {
607 Key(&'de str),
608 Idx { idx: usize, key: &'de str },
609}
610
611#[cfg(test)]
612mod tests {
613 use super::*;
614 use serde::Deserialize;
615 use std::collections::HashMap;
616
617 #[derive(Debug, Deserialize, Eq, PartialEq)]
618 enum MyEnum {
619 A,
620 B,
621 #[serde(rename = "c")]
622 C,
623 }
624
625 #[derive(Debug, Deserialize, Eq, PartialEq)]
626 struct Struct {
627 c: String,
628 b: bool,
629 a: i32,
630 }
631
632 fn create_url_params<I, K, V>(values: I) -> Vec<(Arc<str>, PercentDecodedStr)>
633 where
634 I: IntoIterator<Item = (K, V)>,
635 K: AsRef<str>,
636 V: AsRef<str>,
637 {
638 values
639 .into_iter()
640 .map(|(k, v)| (Arc::from(k.as_ref()), PercentDecodedStr::new(v).unwrap()))
641 .collect()
642 }
643
644 macro_rules! check_single_value {
645 ($ty:ty, $value_str:literal, $value:expr) => {
646 #[allow(clippy::bool_assert_comparison)]
647 {
648 let url_params = create_url_params(vec![("value", $value_str)]);
649 let deserializer = PathDeserializer::new(&url_params);
650 assert_eq!(<$ty>::deserialize(deserializer).unwrap(), $value);
651 }
652 };
653 }
654
655 #[test]
656 fn test_parse_single_value() {
657 check_single_value!(bool, "true", true);
658 check_single_value!(bool, "false", false);
659 check_single_value!(i8, "-123", -123);
660 check_single_value!(i16, "-123", -123);
661 check_single_value!(i32, "-123", -123);
662 check_single_value!(i64, "-123", -123);
663 check_single_value!(i128, "123", 123);
664 check_single_value!(u8, "123", 123);
665 check_single_value!(u16, "123", 123);
666 check_single_value!(u32, "123", 123);
667 check_single_value!(u64, "123", 123);
668 check_single_value!(u128, "123", 123);
669 check_single_value!(f32, "123", 123.0);
670 check_single_value!(f64, "123", 123.0);
671 check_single_value!(String, "abc", "abc");
672 check_single_value!(String, "one%20two", "one two");
673 check_single_value!(&str, "abc", "abc");
674 check_single_value!(&str, "one%20two", "one two");
675 check_single_value!(char, "a", 'a');
676
677 let url_params = create_url_params(vec![("a", "B")]);
678 assert_eq!(
679 MyEnum::deserialize(PathDeserializer::new(&url_params)).unwrap(),
680 MyEnum::B
681 );
682
683 let url_params = create_url_params(vec![("a", "1"), ("b", "2")]);
684 let error_kind = i32::deserialize(PathDeserializer::new(&url_params))
685 .unwrap_err()
686 .kind;
687 assert!(matches!(
688 error_kind,
689 ErrorKind::WrongNumberOfParameters {
690 expected: 1,
691 got: 2
692 }
693 ));
694 }
695
696 #[test]
697 fn test_parse_seq() {
698 let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
699 assert_eq!(
700 <(i32, bool, String)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
701 (1, true, "abc".to_owned())
702 );
703
704 #[derive(Debug, Deserialize, Eq, PartialEq)]
705 struct TupleStruct(i32, bool, String);
706 assert_eq!(
707 TupleStruct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
708 TupleStruct(1, true, "abc".to_owned())
709 );
710
711 let url_params = create_url_params(vec![("a", "1"), ("b", "2"), ("c", "3")]);
712 assert_eq!(
713 <Vec<i32>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
714 vec![1, 2, 3]
715 );
716
717 let url_params = create_url_params(vec![("a", "c"), ("a", "B")]);
718 assert_eq!(
719 <Vec<MyEnum>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
720 vec![MyEnum::C, MyEnum::B]
721 );
722 }
723
724 #[test]
725 fn test_parse_seq_tuple_string_string() {
726 let url_params = create_url_params(vec![("a", "foo"), ("b", "bar")]);
727 assert_eq!(
728 <Vec<(String, String)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
729 vec![
730 ("a".to_owned(), "foo".to_owned()),
731 ("b".to_owned(), "bar".to_owned())
732 ]
733 );
734 }
735
736 #[test]
737 fn test_parse_seq_tuple_string_parse() {
738 let url_params = create_url_params(vec![("a", "1"), ("b", "2")]);
739 assert_eq!(
740 <Vec<(String, u32)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
741 vec![("a".to_owned(), 1), ("b".to_owned(), 2)]
742 );
743 }
744
745 #[test]
746 fn test_parse_struct() {
747 let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
748 assert_eq!(
749 Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
750 Struct {
751 c: "abc".to_owned(),
752 b: true,
753 a: 1,
754 }
755 );
756 }
757
758 #[test]
759 fn test_parse_struct_ignoring_additional_fields() {
760 let url_params = create_url_params(vec![
761 ("a", "1"),
762 ("b", "true"),
763 ("c", "abc"),
764 ("d", "false"),
765 ]);
766 assert_eq!(
767 Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),
768 Struct {
769 c: "abc".to_owned(),
770 b: true,
771 a: 1,
772 }
773 );
774 }
775
776 #[test]
777 fn test_parse_tuple_ignoring_additional_fields() {
778 let url_params = create_url_params(vec![
779 ("a", "abc"),
780 ("b", "true"),
781 ("c", "1"),
782 ("d", "false"),
783 ]);
784 assert_eq!(
785 <(&str, bool, u32)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
786 ("abc", true, 1)
787 );
788 }
789
790 #[test]
791 fn test_parse_map() {
792 let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
793 assert_eq!(
794 <HashMap<String, String>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
795 [("a", "1"), ("b", "true"), ("c", "abc")]
796 .iter()
797 .map(|(key, value)| ((*key).to_owned(), (*value).to_owned()))
798 .collect()
799 );
800 }
801
802 macro_rules! test_parse_error {
803 (
804 $params:expr,
805 $ty:ty,
806 $expected_error_kind:expr $(,)?
807 ) => {
808 let url_params = create_url_params($params);
809 let actual_error_kind = <$ty>::deserialize(PathDeserializer::new(&url_params))
810 .unwrap_err()
811 .kind;
812 assert_eq!(actual_error_kind, $expected_error_kind);
813 };
814 }
815
816 #[test]
817 fn test_wrong_number_of_parameters_error() {
818 test_parse_error!(
819 vec![("a", "1")],
820 (u32, u32),
821 ErrorKind::WrongNumberOfParameters {
822 got: 1,
823 expected: 2,
824 }
825 );
826 }
827
828 #[test]
829 fn test_parse_error_at_key_error() {
830 #[derive(Debug, Deserialize)]
831 #[allow(dead_code)]
832 struct Params {
833 a: u32,
834 }
835 test_parse_error!(
836 vec![("a", "false")],
837 Params,
838 ErrorKind::ParseErrorAtKey {
839 key: "a".to_owned(),
840 value: "false".to_owned(),
841 expected_type: "u32",
842 }
843 );
844 }
845
846 #[test]
847 fn test_parse_error_at_key_error_multiple() {
848 #[derive(Debug, Deserialize)]
849 #[allow(dead_code)]
850 struct Params {
851 a: u32,
852 b: u32,
853 }
854 test_parse_error!(
855 vec![("a", "false")],
856 Params,
857 ErrorKind::ParseErrorAtKey {
858 key: "a".to_owned(),
859 value: "false".to_owned(),
860 expected_type: "u32",
861 }
862 );
863 }
864
865 #[test]
866 fn test_parse_error_at_index_error() {
867 test_parse_error!(
868 vec![("a", "false"), ("b", "true")],
869 (bool, u32),
870 ErrorKind::ParseErrorAtIndex {
871 index: 1,
872 value: "true".to_owned(),
873 expected_type: "u32",
874 }
875 );
876 }
877
878 #[test]
879 fn test_parse_error_error() {
880 test_parse_error!(
881 vec![("a", "false")],
882 u32,
883 ErrorKind::ParseError {
884 value: "false".to_owned(),
885 expected_type: "u32",
886 }
887 );
888 }
889
890 #[test]
891 fn test_unsupported_type_error_nested_data_structure() {
892 test_parse_error!(
893 vec![("a", "false")],
894 Vec<Vec<u32>>,
895 ErrorKind::UnsupportedType {
896 name: "alloc::vec::Vec<u32>",
897 }
898 );
899 }
900
901 #[test]
902 fn test_parse_seq_tuple_unsupported_key_type() {
903 test_parse_error!(
904 vec![("a", "false")],
905 Vec<(u32, String)>,
906 ErrorKind::Message("Unexpected key type".to_owned())
907 );
908 }
909
910 #[test]
911 fn test_parse_seq_wrong_tuple_length() {
912 test_parse_error!(
913 vec![("a", "false")],
914 Vec<(String, String, String)>,
915 ErrorKind::UnsupportedType {
916 name: "(alloc::string::String, alloc::string::String, alloc::string::String)",
917 }
918 );
919 }
920
921 #[test]
922 fn test_parse_seq_seq() {
923 test_parse_error!(
924 vec![("a", "false")],
925 Vec<Vec<String>>,
926 ErrorKind::UnsupportedType {
927 name: "alloc::vec::Vec<alloc::string::String>",
928 }
929 );
930 }
931}