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