1 use super::{ErrorKind, PathDeserializationError}; 2 use crate::util::PercentDecodedStr; 3 use serde::{ 4 de::{self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor}, 5 forward_to_deserialize_any, Deserializer, 6 }; 7 use std::{any::type_name, sync::Arc}; 8 9 macro_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 22 macro_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 45 pub(crate) struct PathDeserializer<'de> { 46 url_params: &'de [(Arc<str>, PercentDecodedStr)], 47 } 48 49 impl<'de> PathDeserializer<'de> { 50 #[inline] new(url_params: &'de [(Arc<str>, PercentDecodedStr)]) -> Self51 pub(crate) fn new(url_params: &'de [(Arc<str>, PercentDecodedStr)]) -> Self { 52 PathDeserializer { url_params } 53 } 54 } 55 56 impl<'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 deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_unit_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_newtype_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_tuple_struct<V>( self, _name: &'static str, len: usize, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_struct<V>( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_enum<V>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 218 struct MapDeserializer<'de> { 219 params: &'de [(Arc<str>, PercentDecodedStr)], 220 key: Option<KeyOrIdx>, 221 value: Option<&'de PercentDecodedStr>, 222 } 223 224 impl<'de> MapAccess<'de> for MapDeserializer<'de> { 225 type Error = PathDeserializationError; 226 next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de>,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 next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> where V: DeserializeSeed<'de>,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 259 struct KeyDeserializer { 260 key: Arc<str>, 261 } 262 263 macro_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 274 impl<'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 deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 295 macro_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)] 329 struct ValueDeserializer<'de> { 330 key: Option<KeyOrIdx>, 331 value: &'de PercentDecodedStr, 332 } 333 334 impl<'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 deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_unit_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_newtype_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 // `KeyOrIdx::Key` is only used when deserializing maps so `deserialize_seq` 435 // wouldn't be called for that 436 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 // `self.key` is only `None` when deserializing maps so `deserialize_seq` 454 // wouldn't be called for that 455 None => unreachable!(), 456 } 457 } else { 458 Err(PathDeserializationError::unsupported_type(type_name::< 459 V::Value, 460 >())) 461 } 462 } 463 deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_tuple_struct<V>( self, _name: &'static str, _len: usize, _visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_struct<V>( self, _name: &'static str, _fields: &'static [&'static str], _visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_enum<V>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 523 struct EnumDeserializer { 524 value: Arc<str>, 525 } 526 527 impl<'de> EnumAccess<'de> for EnumDeserializer { 528 type Error = PathDeserializationError; 529 type Variant = UnitVariant; 530 variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: de::DeserializeSeed<'de>,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 542 struct UnitVariant; 543 544 impl<'de> VariantAccess<'de> for UnitVariant { 545 type Error = PathDeserializationError; 546 unit_variant(self) -> Result<(), Self::Error>547 fn unit_variant(self) -> Result<(), Self::Error> { 548 Ok(()) 549 } 550 newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> where T: DeserializeSeed<'de>,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 tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 struct_variant<V>( self, _fields: &'static [&'static str], _visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,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 583 struct SeqDeserializer<'de> { 584 params: &'de [(Arc<str>, PercentDecodedStr)], 585 idx: usize, 586 } 587 588 impl<'de> SeqAccess<'de> for SeqDeserializer<'de> { 589 type Error = PathDeserializationError; 590 next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> where T: DeserializeSeed<'de>,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)] 614 enum KeyOrIdx { 615 Key(Arc<str>), 616 Idx { idx: usize, key: Arc<str> }, 617 } 618 619 #[cfg(test)] 620 mod 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 create_url_params<I, K, V>(values: I) -> Vec<(Arc<str>, PercentDecodedStr)> where I: IntoIterator<Item = (K, V)>, K: AsRef<str>, V: AsRef<str>,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] test_parse_single_value()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] test_parse_seq()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] test_parse_seq_tuple_string_string()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] test_parse_seq_tuple_string_parse()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] test_parse_struct()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] test_parse_struct_ignoring_additional_fields()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] test_parse_tuple_ignoring_additional_fields()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] test_parse_map()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] test_wrong_number_of_parameters_error()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] test_parse_error_at_key_error()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] test_parse_error_at_key_error_multiple()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] test_parse_error_at_index_error()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] test_parse_error_error()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] test_unsupported_type_error_nested_data_structure()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] test_parse_seq_tuple_unsupported_key_type()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] test_parse_seq_wrong_tuple_length()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] test_parse_seq_seq()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 } 940