1#![allow( 2 clippy::cast_lossless, 3 clippy::derive_partial_eq_without_eq, 4 clippy::from_over_into, 5 // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422 6 clippy::nonstandard_macro_braces, 7 clippy::too_many_lines, 8 clippy::trivially_copy_pass_by_ref, 9 clippy::type_repetition_in_bounds, 10 clippy::uninlined_format_args, 11)] 12 13use serde::de::{self, Deserialize, Deserializer, IgnoredAny, MapAccess, Unexpected, Visitor}; 14use serde::ser::{Serialize, Serializer}; 15use serde_derive::{Deserialize, Serialize}; 16use serde_test::{ 17 assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error, 18 assert_tokens, Token, 19}; 20use std::collections::{BTreeMap, HashMap}; 21use std::convert::TryFrom; 22use std::fmt; 23use std::marker::PhantomData; 24 25trait MyDefault: Sized { 26 fn my_default() -> Self; 27} 28 29trait ShouldSkip: Sized { 30 fn should_skip(&self) -> bool; 31} 32 33trait SerializeWith: Sized { 34 fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> 35 where 36 S: Serializer; 37} 38 39trait DeserializeWith: Sized { 40 fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error> 41 where 42 D: Deserializer<'de>; 43} 44 45impl MyDefault for i32 { 46 fn my_default() -> Self { 47 123 48 } 49} 50 51impl ShouldSkip for i32 { 52 fn should_skip(&self) -> bool { 53 *self == 123 54 } 55} 56 57impl SerializeWith for i32 { 58 fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> 59 where 60 S: Serializer, 61 { 62 if *self == 123 { 63 true.serialize(ser) 64 } else { 65 false.serialize(ser) 66 } 67 } 68} 69 70impl DeserializeWith for i32 { 71 fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error> 72 where 73 D: Deserializer<'de>, 74 { 75 if Deserialize::deserialize(de)? { 76 Ok(123) 77 } else { 78 Ok(2) 79 } 80 } 81} 82 83#[derive(Debug, PartialEq, Serialize, Deserialize)] 84struct DefaultStruct<A, B, C, D, E> 85where 86 C: MyDefault, 87 E: MyDefault, 88{ 89 a1: A, 90 #[serde(default)] 91 a2: B, 92 #[serde(default = "MyDefault::my_default")] 93 a3: C, 94 #[serde(skip_deserializing)] 95 a4: D, 96 #[serde(skip_deserializing, default = "MyDefault::my_default")] 97 a5: E, 98} 99 100#[derive(Debug, PartialEq, Serialize, Deserialize)] 101struct DefaultTupleStruct<A, B, C>( 102 A, 103 #[serde(default)] B, 104 #[serde(default = "MyDefault::my_default")] C, 105) 106where 107 C: MyDefault; 108 109#[derive(Debug, PartialEq, Serialize, Deserialize)] 110struct CollectOther { 111 a: u32, 112 b: u32, 113 #[serde(flatten)] 114 extra: HashMap<String, u32>, 115} 116 117#[test] 118fn test_default_struct() { 119 assert_de_tokens( 120 &DefaultStruct { 121 a1: 1, 122 a2: 2, 123 a3: 3, 124 a4: 0, 125 a5: 123, 126 }, 127 &[ 128 Token::Struct { 129 name: "DefaultStruct", 130 len: 3, 131 }, 132 Token::Str("a1"), 133 Token::I32(1), 134 Token::Str("a2"), 135 Token::I32(2), 136 Token::Str("a3"), 137 Token::I32(3), 138 Token::Str("a4"), 139 Token::I32(4), 140 Token::Str("a5"), 141 Token::I32(5), 142 Token::StructEnd, 143 ], 144 ); 145 146 assert_de_tokens( 147 &DefaultStruct { 148 a1: 1, 149 a2: 0, 150 a3: 123, 151 a4: 0, 152 a5: 123, 153 }, 154 &[ 155 Token::Struct { 156 name: "DefaultStruct", 157 len: 3, 158 }, 159 Token::Str("a1"), 160 Token::I32(1), 161 Token::StructEnd, 162 ], 163 ); 164} 165 166#[test] 167fn test_default_tuple() { 168 assert_de_tokens( 169 &DefaultTupleStruct(1, 2, 3), 170 &[ 171 Token::TupleStruct { 172 name: "DefaultTupleStruct", 173 len: 3, 174 }, 175 Token::I32(1), 176 Token::I32(2), 177 Token::I32(3), 178 Token::TupleStructEnd, 179 ], 180 ); 181 182 assert_de_tokens( 183 &DefaultTupleStruct(1, 0, 123), 184 &[ 185 Token::TupleStruct { 186 name: "DefaultTupleStruct", 187 len: 3, 188 }, 189 Token::I32(1), 190 Token::TupleStructEnd, 191 ], 192 ); 193} 194 195#[derive(Debug, PartialEq, Serialize, Deserialize)] 196enum DefaultStructVariant<A, B, C, D, E> 197where 198 C: MyDefault, 199 E: MyDefault, 200{ 201 Struct { 202 a1: A, 203 #[serde(default)] 204 a2: B, 205 #[serde(default = "MyDefault::my_default")] 206 a3: C, 207 #[serde(skip_deserializing)] 208 a4: D, 209 #[serde(skip_deserializing, default = "MyDefault::my_default")] 210 a5: E, 211 }, 212} 213 214#[derive(Debug, PartialEq, Serialize, Deserialize)] 215enum DefaultTupleVariant<A, B, C> 216where 217 C: MyDefault, 218{ 219 Tuple( 220 A, 221 #[serde(default)] B, 222 #[serde(default = "MyDefault::my_default")] C, 223 ), 224} 225 226#[test] 227fn test_default_struct_variant() { 228 assert_de_tokens( 229 &DefaultStructVariant::Struct { 230 a1: 1, 231 a2: 2, 232 a3: 3, 233 a4: 0, 234 a5: 123, 235 }, 236 &[ 237 Token::StructVariant { 238 name: "DefaultStructVariant", 239 variant: "Struct", 240 len: 3, 241 }, 242 Token::Str("a1"), 243 Token::I32(1), 244 Token::Str("a2"), 245 Token::I32(2), 246 Token::Str("a3"), 247 Token::I32(3), 248 Token::Str("a4"), 249 Token::I32(4), 250 Token::Str("a5"), 251 Token::I32(5), 252 Token::StructVariantEnd, 253 ], 254 ); 255 256 assert_de_tokens( 257 &DefaultStructVariant::Struct { 258 a1: 1, 259 a2: 0, 260 a3: 123, 261 a4: 0, 262 a5: 123, 263 }, 264 &[ 265 Token::StructVariant { 266 name: "DefaultStructVariant", 267 variant: "Struct", 268 len: 3, 269 }, 270 Token::Str("a1"), 271 Token::I32(1), 272 Token::StructVariantEnd, 273 ], 274 ); 275} 276 277#[test] 278fn test_default_tuple_variant() { 279 assert_de_tokens( 280 &DefaultTupleVariant::Tuple(1, 2, 3), 281 &[ 282 Token::TupleVariant { 283 name: "DefaultTupleVariant", 284 variant: "Tuple", 285 len: 3, 286 }, 287 Token::I32(1), 288 Token::I32(2), 289 Token::I32(3), 290 Token::TupleVariantEnd, 291 ], 292 ); 293 294 assert_de_tokens( 295 &DefaultTupleVariant::Tuple(1, 0, 123), 296 &[ 297 Token::TupleVariant { 298 name: "DefaultTupleVariant", 299 variant: "Tuple", 300 len: 3, 301 }, 302 Token::I32(1), 303 Token::TupleVariantEnd, 304 ], 305 ); 306} 307 308// Does not implement std::default::Default. 309#[derive(Debug, PartialEq, Deserialize)] 310struct NoStdDefault(i8); 311 312impl MyDefault for NoStdDefault { 313 fn my_default() -> Self { 314 NoStdDefault(123) 315 } 316} 317 318#[derive(Debug, PartialEq, Deserialize)] 319struct ContainsNoStdDefault<A: MyDefault> { 320 #[serde(default = "MyDefault::my_default")] 321 a: A, 322} 323 324// Tests that a struct field does not need to implement std::default::Default if 325// it is annotated with `default=...`. 326#[test] 327fn test_no_std_default() { 328 assert_de_tokens( 329 &ContainsNoStdDefault { 330 a: NoStdDefault(123), 331 }, 332 &[ 333 Token::Struct { 334 name: "ContainsNoStdDefault", 335 len: 1, 336 }, 337 Token::StructEnd, 338 ], 339 ); 340 341 assert_de_tokens( 342 &ContainsNoStdDefault { a: NoStdDefault(8) }, 343 &[ 344 Token::Struct { 345 name: "ContainsNoStdDefault", 346 len: 1, 347 }, 348 Token::Str("a"), 349 Token::NewtypeStruct { 350 name: "NoStdDefault", 351 }, 352 Token::I8(8), 353 Token::StructEnd, 354 ], 355 ); 356} 357 358// Does not implement Deserialize. 359#[derive(Debug, PartialEq)] 360struct NotDeserializeStruct(i8); 361 362impl Default for NotDeserializeStruct { 363 fn default() -> Self { 364 NotDeserializeStruct(123) 365 } 366} 367 368impl DeserializeWith for NotDeserializeStruct { 369 fn deserialize_with<'de, D>(_: D) -> Result<Self, D::Error> 370 where 371 D: Deserializer<'de>, 372 { 373 panic!() 374 } 375} 376 377// Does not implement Deserialize. 378#[derive(Debug, PartialEq)] 379enum NotDeserializeEnum { 380 Trouble, 381} 382 383impl MyDefault for NotDeserializeEnum { 384 fn my_default() -> Self { 385 NotDeserializeEnum::Trouble 386 } 387} 388 389#[derive(Debug, PartialEq, Deserialize)] 390struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> { 391 #[serde(skip_deserializing)] 392 a: A, 393 #[serde(skip_deserializing, default)] 394 b: B, 395 #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)] 396 c: C, 397 #[serde(skip_deserializing, default = "MyDefault::my_default")] 398 e: E, 399} 400 401// Tests that a struct field does not need to implement Deserialize if it is 402// annotated with skip_deserializing, whether using the std Default or a 403// custom default. 404#[test] 405fn test_elt_not_deserialize() { 406 assert_de_tokens( 407 &ContainsNotDeserialize { 408 a: NotDeserializeStruct(123), 409 b: NotDeserializeStruct(123), 410 c: NotDeserializeStruct(123), 411 e: NotDeserializeEnum::Trouble, 412 }, 413 &[ 414 Token::Struct { 415 name: "ContainsNotDeserialize", 416 len: 1, 417 }, 418 Token::StructEnd, 419 ], 420 ); 421} 422 423#[derive(Debug, PartialEq, Serialize, Deserialize)] 424#[serde(deny_unknown_fields)] 425struct DenyUnknown { 426 a1: i32, 427} 428 429#[test] 430fn test_ignore_unknown() { 431 // 'Default' allows unknown. Basic smoke test of ignore... 432 assert_de_tokens( 433 &DefaultStruct { 434 a1: 1, 435 a2: 2, 436 a3: 3, 437 a4: 0, 438 a5: 123, 439 }, 440 &[ 441 Token::Struct { 442 name: "DefaultStruct", 443 len: 3, 444 }, 445 Token::Str("whoops1"), 446 Token::I32(2), 447 Token::Str("a1"), 448 Token::I32(1), 449 Token::Str("whoops2"), 450 Token::Seq { len: Some(1) }, 451 Token::I32(2), 452 Token::SeqEnd, 453 Token::Str("a2"), 454 Token::I32(2), 455 Token::Str("whoops3"), 456 Token::I32(2), 457 Token::Str("a3"), 458 Token::I32(3), 459 Token::StructEnd, 460 ], 461 ); 462 463 assert_de_tokens_error::<DenyUnknown>( 464 &[ 465 Token::Struct { 466 name: "DenyUnknown", 467 len: 1, 468 }, 469 Token::Str("a1"), 470 Token::I32(1), 471 Token::Str("whoops"), 472 ], 473 "unknown field `whoops`, expected `a1`", 474 ); 475} 476 477#[derive(Debug, PartialEq, Serialize, Deserialize)] 478#[serde(rename = "Superhero")] 479struct RenameStruct { 480 a1: i32, 481 #[serde(rename = "a3")] 482 a2: i32, 483} 484 485#[derive(Debug, PartialEq, Serialize, Deserialize)] 486#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))] 487struct RenameStructSerializeDeserialize { 488 a1: i32, 489 #[serde(rename(serialize = "a4", deserialize = "a5"))] 490 a2: i32, 491} 492 493#[derive(Debug, PartialEq, Deserialize)] 494#[serde(deny_unknown_fields)] 495struct AliasStruct { 496 a1: i32, 497 #[serde(alias = "a3")] 498 a2: i32, 499 #[serde(alias = "a5", rename = "a6")] 500 a4: i32, 501} 502 503#[test] 504fn test_rename_struct() { 505 assert_tokens( 506 &RenameStruct { a1: 1, a2: 2 }, 507 &[ 508 Token::Struct { 509 name: "Superhero", 510 len: 2, 511 }, 512 Token::Str("a1"), 513 Token::I32(1), 514 Token::Str("a3"), 515 Token::I32(2), 516 Token::StructEnd, 517 ], 518 ); 519 520 assert_ser_tokens( 521 &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, 522 &[ 523 Token::Struct { 524 name: "SuperheroSer", 525 len: 2, 526 }, 527 Token::Str("a1"), 528 Token::I32(1), 529 Token::Str("a4"), 530 Token::I32(2), 531 Token::StructEnd, 532 ], 533 ); 534 535 assert_de_tokens( 536 &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, 537 &[ 538 Token::Struct { 539 name: "SuperheroDe", 540 len: 2, 541 }, 542 Token::Str("a1"), 543 Token::I32(1), 544 Token::Str("a5"), 545 Token::I32(2), 546 Token::StructEnd, 547 ], 548 ); 549 550 assert_de_tokens( 551 &AliasStruct { 552 a1: 1, 553 a2: 2, 554 a4: 3, 555 }, 556 &[ 557 Token::Struct { 558 name: "AliasStruct", 559 len: 3, 560 }, 561 Token::Str("a1"), 562 Token::I32(1), 563 Token::Str("a2"), 564 Token::I32(2), 565 Token::Str("a5"), 566 Token::I32(3), 567 Token::StructEnd, 568 ], 569 ); 570 571 assert_de_tokens( 572 &AliasStruct { 573 a1: 1, 574 a2: 2, 575 a4: 3, 576 }, 577 &[ 578 Token::Struct { 579 name: "AliasStruct", 580 len: 3, 581 }, 582 Token::Str("a1"), 583 Token::I32(1), 584 Token::Str("a3"), 585 Token::I32(2), 586 Token::Str("a6"), 587 Token::I32(3), 588 Token::StructEnd, 589 ], 590 ); 591} 592 593#[test] 594fn test_unknown_field_rename_struct() { 595 assert_de_tokens_error::<AliasStruct>( 596 &[ 597 Token::Struct { 598 name: "AliasStruct", 599 len: 3, 600 }, 601 Token::Str("a1"), 602 Token::I32(1), 603 Token::Str("a3"), 604 Token::I32(2), 605 Token::Str("a4"), 606 Token::I32(3), 607 ], 608 "unknown field `a4`, expected one of `a1`, `a2`, `a3`, `a5`, `a6`", 609 ); 610} 611 612#[derive(Debug, PartialEq, Serialize, Deserialize)] 613#[serde(rename = "Superhero")] 614enum RenameEnum { 615 #[serde(rename = "bruce_wayne")] 616 Batman, 617 #[serde(rename = "clark_kent")] 618 Superman(i8), 619 #[serde(rename = "diana_prince")] 620 WonderWoman(i8, i8), 621 #[serde(rename = "barry_allan")] 622 Flash { 623 #[serde(rename = "b")] 624 a: i32, 625 }, 626} 627 628#[derive(Debug, PartialEq, Deserialize, Serialize)] 629#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))] 630enum RenameEnumSerializeDeserialize<A> { 631 #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))] 632 Robin { 633 a: i8, 634 #[serde(rename(serialize = "c"))] 635 #[serde(rename(deserialize = "d"))] 636 b: A, 637 }, 638} 639 640#[derive(Debug, PartialEq, Deserialize)] 641#[serde(deny_unknown_fields)] 642enum AliasEnum { 643 #[serde(rename = "sailor_moon", alias = "usagi_tsukino")] 644 SailorMoon { 645 a: i8, 646 #[serde(alias = "c")] 647 b: i8, 648 #[serde(alias = "e", rename = "f")] 649 d: i8, 650 }, 651} 652 653#[test] 654fn test_rename_enum() { 655 assert_tokens( 656 &RenameEnum::Batman, 657 &[Token::UnitVariant { 658 name: "Superhero", 659 variant: "bruce_wayne", 660 }], 661 ); 662 663 assert_tokens( 664 &RenameEnum::Superman(0), 665 &[ 666 Token::NewtypeVariant { 667 name: "Superhero", 668 variant: "clark_kent", 669 }, 670 Token::I8(0), 671 ], 672 ); 673 674 assert_tokens( 675 &RenameEnum::WonderWoman(0, 1), 676 &[ 677 Token::TupleVariant { 678 name: "Superhero", 679 variant: "diana_prince", 680 len: 2, 681 }, 682 Token::I8(0), 683 Token::I8(1), 684 Token::TupleVariantEnd, 685 ], 686 ); 687 688 assert_tokens( 689 &RenameEnum::Flash { a: 1 }, 690 &[ 691 Token::StructVariant { 692 name: "Superhero", 693 variant: "barry_allan", 694 len: 1, 695 }, 696 Token::Str("b"), 697 Token::I32(1), 698 Token::StructVariantEnd, 699 ], 700 ); 701 702 assert_ser_tokens( 703 &RenameEnumSerializeDeserialize::Robin { 704 a: 0, 705 b: String::new(), 706 }, 707 &[ 708 Token::StructVariant { 709 name: "SuperheroSer", 710 variant: "dick_grayson", 711 len: 2, 712 }, 713 Token::Str("a"), 714 Token::I8(0), 715 Token::Str("c"), 716 Token::Str(""), 717 Token::StructVariantEnd, 718 ], 719 ); 720 721 assert_de_tokens( 722 &RenameEnumSerializeDeserialize::Robin { 723 a: 0, 724 b: String::new(), 725 }, 726 &[ 727 Token::StructVariant { 728 name: "SuperheroDe", 729 variant: "jason_todd", 730 len: 2, 731 }, 732 Token::Str("a"), 733 Token::I8(0), 734 Token::Str("d"), 735 Token::Str(""), 736 Token::StructVariantEnd, 737 ], 738 ); 739 740 assert_de_tokens( 741 &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 }, 742 &[ 743 Token::StructVariant { 744 name: "AliasEnum", 745 variant: "sailor_moon", 746 len: 5, 747 }, 748 Token::Str("a"), 749 Token::I8(0), 750 Token::Str("b"), 751 Token::I8(1), 752 Token::Str("e"), 753 Token::I8(2), 754 Token::StructVariantEnd, 755 ], 756 ); 757 758 assert_de_tokens( 759 &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 }, 760 &[ 761 Token::StructVariant { 762 name: "AliasEnum", 763 variant: "usagi_tsukino", 764 len: 5, 765 }, 766 Token::Str("a"), 767 Token::I8(0), 768 Token::Str("c"), 769 Token::I8(1), 770 Token::Str("f"), 771 Token::I8(2), 772 Token::StructVariantEnd, 773 ], 774 ); 775} 776 777#[test] 778fn test_unknown_field_rename_enum() { 779 assert_de_tokens_error::<AliasEnum>( 780 &[Token::StructVariant { 781 name: "AliasEnum", 782 variant: "SailorMoon", 783 len: 3, 784 }], 785 "unknown variant `SailorMoon`, expected `sailor_moon`", 786 ); 787 788 assert_de_tokens_error::<AliasEnum>( 789 &[ 790 Token::StructVariant { 791 name: "AliasEnum", 792 variant: "usagi_tsukino", 793 len: 5, 794 }, 795 Token::Str("a"), 796 Token::I8(0), 797 Token::Str("c"), 798 Token::I8(1), 799 Token::Str("d"), 800 Token::I8(2), 801 ], 802 "unknown field `d`, expected one of `a`, `b`, `c`, `e`, `f`", 803 ); 804} 805 806#[derive(Debug, PartialEq, Serialize)] 807struct SkipSerializingStruct<'a, B, C> 808where 809 C: ShouldSkip, 810{ 811 a: &'a i8, 812 #[serde(skip_serializing)] 813 b: B, 814 #[serde(skip_serializing_if = "ShouldSkip::should_skip")] 815 c: C, 816} 817 818#[test] 819fn test_skip_serializing_struct() { 820 let a = 1; 821 assert_ser_tokens( 822 &SkipSerializingStruct { a: &a, b: 2, c: 3 }, 823 &[ 824 Token::Struct { 825 name: "SkipSerializingStruct", 826 len: 2, 827 }, 828 Token::Str("a"), 829 Token::I8(1), 830 Token::Str("c"), 831 Token::I32(3), 832 Token::StructEnd, 833 ], 834 ); 835 836 assert_ser_tokens( 837 &SkipSerializingStruct { 838 a: &a, 839 b: 2, 840 c: 123, 841 }, 842 &[ 843 Token::Struct { 844 name: "SkipSerializingStruct", 845 len: 1, 846 }, 847 Token::Str("a"), 848 Token::I8(1), 849 Token::StructEnd, 850 ], 851 ); 852} 853 854#[derive(Debug, PartialEq, Serialize)] 855struct SkipSerializingTupleStruct<'a, B, C>( 856 &'a i8, 857 #[serde(skip_serializing)] B, 858 #[serde(skip_serializing_if = "ShouldSkip::should_skip")] C, 859) 860where 861 C: ShouldSkip; 862 863#[test] 864fn test_skip_serializing_tuple_struct() { 865 let a = 1; 866 assert_ser_tokens( 867 &SkipSerializingTupleStruct(&a, 2, 3), 868 &[ 869 Token::TupleStruct { 870 name: "SkipSerializingTupleStruct", 871 len: 2, 872 }, 873 Token::I8(1), 874 Token::I32(3), 875 Token::TupleStructEnd, 876 ], 877 ); 878 879 assert_ser_tokens( 880 &SkipSerializingTupleStruct(&a, 2, 123), 881 &[ 882 Token::TupleStruct { 883 name: "SkipSerializingTupleStruct", 884 len: 1, 885 }, 886 Token::I8(1), 887 Token::TupleStructEnd, 888 ], 889 ); 890} 891 892#[derive(Debug, PartialEq, Serialize, Deserialize)] 893struct SkipStruct<B> { 894 a: i8, 895 #[serde(skip)] 896 b: B, 897} 898 899#[test] 900fn test_skip_struct() { 901 assert_ser_tokens( 902 &SkipStruct { a: 1, b: 2 }, 903 &[ 904 Token::Struct { 905 name: "SkipStruct", 906 len: 1, 907 }, 908 Token::Str("a"), 909 Token::I8(1), 910 Token::StructEnd, 911 ], 912 ); 913 914 assert_de_tokens( 915 &SkipStruct { a: 1, b: 0 }, 916 &[ 917 Token::Struct { 918 name: "SkipStruct", 919 len: 1, 920 }, 921 Token::Str("a"), 922 Token::I8(1), 923 Token::StructEnd, 924 ], 925 ); 926} 927 928#[derive(Debug, PartialEq, Serialize)] 929enum SkipSerializingEnum<'a, B, C> 930where 931 C: ShouldSkip, 932{ 933 Struct { 934 a: &'a i8, 935 #[serde(skip_serializing)] 936 _b: B, 937 #[serde(skip_serializing_if = "ShouldSkip::should_skip")] 938 c: C, 939 }, 940 Tuple( 941 &'a i8, 942 #[serde(skip_serializing)] B, 943 #[serde(skip_serializing_if = "ShouldSkip::should_skip")] C, 944 ), 945} 946 947#[test] 948fn test_skip_serializing_enum() { 949 let a = 1; 950 assert_ser_tokens( 951 &SkipSerializingEnum::Struct { a: &a, _b: 2, c: 3 }, 952 &[ 953 Token::StructVariant { 954 name: "SkipSerializingEnum", 955 variant: "Struct", 956 len: 2, 957 }, 958 Token::Str("a"), 959 Token::I8(1), 960 Token::Str("c"), 961 Token::I32(3), 962 Token::StructVariantEnd, 963 ], 964 ); 965 966 assert_ser_tokens( 967 &SkipSerializingEnum::Struct { 968 a: &a, 969 _b: 2, 970 c: 123, 971 }, 972 &[ 973 Token::StructVariant { 974 name: "SkipSerializingEnum", 975 variant: "Struct", 976 len: 1, 977 }, 978 Token::Str("a"), 979 Token::I8(1), 980 Token::StructVariantEnd, 981 ], 982 ); 983 984 assert_ser_tokens( 985 &SkipSerializingEnum::Tuple(&a, 2, 3), 986 &[ 987 Token::TupleVariant { 988 name: "SkipSerializingEnum", 989 variant: "Tuple", 990 len: 2, 991 }, 992 Token::I8(1), 993 Token::I32(3), 994 Token::TupleVariantEnd, 995 ], 996 ); 997 998 assert_ser_tokens( 999 &SkipSerializingEnum::Tuple(&a, 2, 123), 1000 &[ 1001 Token::TupleVariant { 1002 name: "SkipSerializingEnum", 1003 variant: "Tuple", 1004 len: 1, 1005 }, 1006 Token::I8(1), 1007 Token::TupleVariantEnd, 1008 ], 1009 ); 1010} 1011 1012#[derive(Debug, PartialEq)] 1013struct NotSerializeStruct(i8); 1014 1015#[derive(Debug, PartialEq)] 1016enum NotSerializeEnum { 1017 Trouble, 1018} 1019 1020impl SerializeWith for NotSerializeEnum { 1021 fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> 1022 where 1023 S: Serializer, 1024 { 1025 "trouble".serialize(ser) 1026 } 1027} 1028 1029#[derive(Debug, PartialEq, Serialize)] 1030struct ContainsNotSerialize<'a, B, C, D> 1031where 1032 B: 'a, 1033 D: SerializeWith, 1034{ 1035 a: &'a Option<i8>, 1036 #[serde(skip_serializing)] 1037 b: &'a B, 1038 #[serde(skip_serializing)] 1039 c: Option<C>, 1040 #[serde(serialize_with = "SerializeWith::serialize_with")] 1041 d: D, 1042} 1043 1044#[test] 1045fn test_elt_not_serialize() { 1046 let a = 1; 1047 assert_ser_tokens( 1048 &ContainsNotSerialize { 1049 a: &Some(a), 1050 b: &NotSerializeStruct(2), 1051 c: Some(NotSerializeEnum::Trouble), 1052 d: NotSerializeEnum::Trouble, 1053 }, 1054 &[ 1055 Token::Struct { 1056 name: "ContainsNotSerialize", 1057 len: 2, 1058 }, 1059 Token::Str("a"), 1060 Token::Some, 1061 Token::I8(1), 1062 Token::Str("d"), 1063 Token::Str("trouble"), 1064 Token::StructEnd, 1065 ], 1066 ); 1067} 1068 1069#[derive(Debug, PartialEq, Serialize)] 1070struct SerializeWithStruct<'a, B> 1071where 1072 B: SerializeWith, 1073{ 1074 a: &'a i8, 1075 #[serde(serialize_with = "SerializeWith::serialize_with")] 1076 b: B, 1077} 1078 1079#[test] 1080fn test_serialize_with_struct() { 1081 let a = 1; 1082 assert_ser_tokens( 1083 &SerializeWithStruct { a: &a, b: 2 }, 1084 &[ 1085 Token::Struct { 1086 name: "SerializeWithStruct", 1087 len: 2, 1088 }, 1089 Token::Str("a"), 1090 Token::I8(1), 1091 Token::Str("b"), 1092 Token::Bool(false), 1093 Token::StructEnd, 1094 ], 1095 ); 1096 1097 assert_ser_tokens( 1098 &SerializeWithStruct { a: &a, b: 123 }, 1099 &[ 1100 Token::Struct { 1101 name: "SerializeWithStruct", 1102 len: 2, 1103 }, 1104 Token::Str("a"), 1105 Token::I8(1), 1106 Token::Str("b"), 1107 Token::Bool(true), 1108 Token::StructEnd, 1109 ], 1110 ); 1111} 1112 1113#[derive(Debug, PartialEq, Serialize)] 1114enum SerializeWithEnum<'a, B> 1115where 1116 B: SerializeWith, 1117{ 1118 Struct { 1119 a: &'a i8, 1120 #[serde(serialize_with = "SerializeWith::serialize_with")] 1121 b: B, 1122 }, 1123} 1124 1125#[test] 1126fn test_serialize_with_enum() { 1127 let a = 1; 1128 assert_ser_tokens( 1129 &SerializeWithEnum::Struct { a: &a, b: 2 }, 1130 &[ 1131 Token::StructVariant { 1132 name: "SerializeWithEnum", 1133 variant: "Struct", 1134 len: 2, 1135 }, 1136 Token::Str("a"), 1137 Token::I8(1), 1138 Token::Str("b"), 1139 Token::Bool(false), 1140 Token::StructVariantEnd, 1141 ], 1142 ); 1143 1144 assert_ser_tokens( 1145 &SerializeWithEnum::Struct { a: &a, b: 123 }, 1146 &[ 1147 Token::StructVariant { 1148 name: "SerializeWithEnum", 1149 variant: "Struct", 1150 len: 2, 1151 }, 1152 Token::Str("a"), 1153 Token::I8(1), 1154 Token::Str("b"), 1155 Token::Bool(true), 1156 Token::StructVariantEnd, 1157 ], 1158 ); 1159} 1160 1161#[derive(Debug, PartialEq, Serialize, Deserialize)] 1162enum WithVariant { 1163 #[serde(serialize_with = "serialize_unit_variant_as_i8")] 1164 #[serde(deserialize_with = "deserialize_i8_as_unit_variant")] 1165 Unit, 1166 1167 #[serde(serialize_with = "SerializeWith::serialize_with")] 1168 #[serde(deserialize_with = "DeserializeWith::deserialize_with")] 1169 Newtype(i32), 1170 1171 #[serde(serialize_with = "serialize_variant_as_string")] 1172 #[serde(deserialize_with = "deserialize_string_as_variant")] 1173 Tuple(String, u8), 1174 1175 #[serde(serialize_with = "serialize_variant_as_string")] 1176 #[serde(deserialize_with = "deserialize_string_as_variant")] 1177 Struct { f1: String, f2: u8 }, 1178} 1179 1180fn serialize_unit_variant_as_i8<S>(serializer: S) -> Result<S::Ok, S::Error> 1181where 1182 S: Serializer, 1183{ 1184 serializer.serialize_i8(0) 1185} 1186 1187fn deserialize_i8_as_unit_variant<'de, D>(deserializer: D) -> Result<(), D::Error> 1188where 1189 D: Deserializer<'de>, 1190{ 1191 let n = i8::deserialize(deserializer)?; 1192 match n { 1193 0 => Ok(()), 1194 _ => Err(de::Error::invalid_value(Unexpected::Signed(n as i64), &"0")), 1195 } 1196} 1197 1198fn serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S::Ok, S::Error> 1199where 1200 S: Serializer, 1201{ 1202 serializer.collect_str(&format_args!("{};{:?}", f1, f2)) 1203} 1204 1205fn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error> 1206where 1207 D: Deserializer<'de>, 1208{ 1209 let s = String::deserialize(deserializer)?; 1210 let mut pieces = s.split(';'); 1211 let Some(f1) = pieces.next() else { 1212 return Err(de::Error::invalid_length(0, &"2")); 1213 }; 1214 let Some(f2) = pieces.next() else { 1215 return Err(de::Error::invalid_length(1, &"2")); 1216 }; 1217 let Ok(f2) = f2.parse() else { 1218 return Err(de::Error::invalid_value( 1219 Unexpected::Str(f2), 1220 &"an 8-bit signed integer", 1221 )); 1222 }; 1223 Ok((f1.into(), f2)) 1224} 1225 1226#[test] 1227fn test_serialize_with_variant() { 1228 assert_ser_tokens( 1229 &WithVariant::Unit, 1230 &[ 1231 Token::NewtypeVariant { 1232 name: "WithVariant", 1233 variant: "Unit", 1234 }, 1235 Token::I8(0), 1236 ], 1237 ); 1238 1239 assert_ser_tokens( 1240 &WithVariant::Newtype(123), 1241 &[ 1242 Token::NewtypeVariant { 1243 name: "WithVariant", 1244 variant: "Newtype", 1245 }, 1246 Token::Bool(true), 1247 ], 1248 ); 1249 1250 assert_ser_tokens( 1251 &WithVariant::Tuple("hello".into(), 0), 1252 &[ 1253 Token::NewtypeVariant { 1254 name: "WithVariant", 1255 variant: "Tuple", 1256 }, 1257 Token::Str("hello;0"), 1258 ], 1259 ); 1260 1261 assert_ser_tokens( 1262 &WithVariant::Struct { 1263 f1: "world".into(), 1264 f2: 1, 1265 }, 1266 &[ 1267 Token::NewtypeVariant { 1268 name: "WithVariant", 1269 variant: "Struct", 1270 }, 1271 Token::Str("world;1"), 1272 ], 1273 ); 1274} 1275 1276#[test] 1277fn test_deserialize_with_variant() { 1278 assert_de_tokens( 1279 &WithVariant::Unit, 1280 &[ 1281 Token::NewtypeVariant { 1282 name: "WithVariant", 1283 variant: "Unit", 1284 }, 1285 Token::I8(0), 1286 ], 1287 ); 1288 1289 assert_de_tokens( 1290 &WithVariant::Newtype(123), 1291 &[ 1292 Token::NewtypeVariant { 1293 name: "WithVariant", 1294 variant: "Newtype", 1295 }, 1296 Token::Bool(true), 1297 ], 1298 ); 1299 1300 assert_de_tokens( 1301 &WithVariant::Tuple("hello".into(), 0), 1302 &[ 1303 Token::NewtypeVariant { 1304 name: "WithVariant", 1305 variant: "Tuple", 1306 }, 1307 Token::Str("hello;0"), 1308 ], 1309 ); 1310 1311 assert_de_tokens( 1312 &WithVariant::Struct { 1313 f1: "world".into(), 1314 f2: 1, 1315 }, 1316 &[ 1317 Token::NewtypeVariant { 1318 name: "WithVariant", 1319 variant: "Struct", 1320 }, 1321 Token::Str("world;1"), 1322 ], 1323 ); 1324} 1325 1326#[derive(Debug, PartialEq, Deserialize)] 1327struct DeserializeWithStruct<B> 1328where 1329 B: DeserializeWith, 1330{ 1331 a: i8, 1332 #[serde(deserialize_with = "DeserializeWith::deserialize_with")] 1333 b: B, 1334} 1335 1336#[test] 1337fn test_deserialize_with_struct() { 1338 assert_de_tokens( 1339 &DeserializeWithStruct { a: 1, b: 2 }, 1340 &[ 1341 Token::Struct { 1342 name: "DeserializeWithStruct", 1343 len: 2, 1344 }, 1345 Token::Str("a"), 1346 Token::I8(1), 1347 Token::Str("b"), 1348 Token::Bool(false), 1349 Token::StructEnd, 1350 ], 1351 ); 1352 1353 assert_de_tokens( 1354 &DeserializeWithStruct { a: 1, b: 123 }, 1355 &[ 1356 Token::Struct { 1357 name: "DeserializeWithStruct", 1358 len: 2, 1359 }, 1360 Token::Str("a"), 1361 Token::I8(1), 1362 Token::Str("b"), 1363 Token::Bool(true), 1364 Token::StructEnd, 1365 ], 1366 ); 1367} 1368 1369#[derive(Debug, PartialEq, Deserialize)] 1370enum DeserializeWithEnum<B> 1371where 1372 B: DeserializeWith, 1373{ 1374 Struct { 1375 a: i8, 1376 #[serde(deserialize_with = "DeserializeWith::deserialize_with")] 1377 b: B, 1378 }, 1379} 1380 1381#[test] 1382fn test_deserialize_with_enum() { 1383 assert_de_tokens( 1384 &DeserializeWithEnum::Struct { a: 1, b: 2 }, 1385 &[ 1386 Token::StructVariant { 1387 name: "DeserializeWithEnum", 1388 variant: "Struct", 1389 len: 2, 1390 }, 1391 Token::Str("a"), 1392 Token::I8(1), 1393 Token::Str("b"), 1394 Token::Bool(false), 1395 Token::StructVariantEnd, 1396 ], 1397 ); 1398 1399 assert_de_tokens( 1400 &DeserializeWithEnum::Struct { a: 1, b: 123 }, 1401 &[ 1402 Token::StructVariant { 1403 name: "DeserializeWithEnum", 1404 variant: "Struct", 1405 len: 2, 1406 }, 1407 Token::Str("a"), 1408 Token::I8(1), 1409 Token::Str("b"), 1410 Token::Bool(true), 1411 Token::StructVariantEnd, 1412 ], 1413 ); 1414} 1415 1416#[test] 1417fn test_missing_renamed_field_struct() { 1418 assert_de_tokens_error::<RenameStruct>( 1419 &[ 1420 Token::Struct { 1421 name: "Superhero", 1422 len: 2, 1423 }, 1424 Token::Str("a1"), 1425 Token::I32(1), 1426 Token::StructEnd, 1427 ], 1428 "missing field `a3`", 1429 ); 1430 1431 assert_de_tokens_error::<RenameStructSerializeDeserialize>( 1432 &[ 1433 Token::Struct { 1434 name: "SuperheroDe", 1435 len: 2, 1436 }, 1437 Token::Str("a1"), 1438 Token::I32(1), 1439 Token::StructEnd, 1440 ], 1441 "missing field `a5`", 1442 ); 1443} 1444 1445#[test] 1446fn test_missing_renamed_field_enum() { 1447 assert_de_tokens_error::<RenameEnum>( 1448 &[ 1449 Token::StructVariant { 1450 name: "Superhero", 1451 variant: "barry_allan", 1452 len: 1, 1453 }, 1454 Token::StructVariantEnd, 1455 ], 1456 "missing field `b`", 1457 ); 1458 1459 assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>( 1460 &[ 1461 Token::StructVariant { 1462 name: "SuperheroDe", 1463 variant: "jason_todd", 1464 len: 2, 1465 }, 1466 Token::Str("a"), 1467 Token::I8(0), 1468 Token::StructVariantEnd, 1469 ], 1470 "missing field `d`", 1471 ); 1472} 1473 1474#[derive(Debug, PartialEq, Deserialize)] 1475enum InvalidLengthEnum { 1476 A(i32, i32, i32), 1477 B(#[serde(skip_deserializing)] i32, i32, i32), 1478} 1479 1480#[test] 1481fn test_invalid_length_enum() { 1482 assert_de_tokens_error::<InvalidLengthEnum>( 1483 &[ 1484 Token::TupleVariant { 1485 name: "InvalidLengthEnum", 1486 variant: "A", 1487 len: 3, 1488 }, 1489 Token::I32(1), 1490 Token::TupleVariantEnd, 1491 ], 1492 "invalid length 1, expected tuple variant InvalidLengthEnum::A with 3 elements", 1493 ); 1494 assert_de_tokens_error::<InvalidLengthEnum>( 1495 &[ 1496 Token::TupleVariant { 1497 name: "InvalidLengthEnum", 1498 variant: "B", 1499 len: 2, 1500 }, 1501 Token::I32(1), 1502 Token::TupleVariantEnd, 1503 ], 1504 "invalid length 1, expected tuple variant InvalidLengthEnum::B with 2 elements", 1505 ); 1506} 1507 1508#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)] 1509#[serde(into = "EnumToU32", from = "EnumToU32")] 1510struct StructFromEnum(Option<u32>); 1511 1512impl Into<EnumToU32> for StructFromEnum { 1513 fn into(self) -> EnumToU32 { 1514 match self { 1515 StructFromEnum(v) => v.into(), 1516 } 1517 } 1518} 1519 1520impl From<EnumToU32> for StructFromEnum { 1521 fn from(v: EnumToU32) -> Self { 1522 StructFromEnum(v.into()) 1523 } 1524} 1525 1526#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)] 1527#[serde(into = "Option<u32>", from = "Option<u32>")] 1528enum EnumToU32 { 1529 One, 1530 Two, 1531 Three, 1532 Four, 1533 Nothing, 1534} 1535 1536impl Into<Option<u32>> for EnumToU32 { 1537 fn into(self) -> Option<u32> { 1538 match self { 1539 EnumToU32::One => Some(1), 1540 EnumToU32::Two => Some(2), 1541 EnumToU32::Three => Some(3), 1542 EnumToU32::Four => Some(4), 1543 EnumToU32::Nothing => None, 1544 } 1545 } 1546} 1547 1548impl From<Option<u32>> for EnumToU32 { 1549 fn from(v: Option<u32>) -> Self { 1550 match v { 1551 Some(1) => EnumToU32::One, 1552 Some(2) => EnumToU32::Two, 1553 Some(3) => EnumToU32::Three, 1554 Some(4) => EnumToU32::Four, 1555 _ => EnumToU32::Nothing, 1556 } 1557 } 1558} 1559 1560#[derive(Clone, Deserialize, PartialEq, Debug)] 1561#[serde(try_from = "u32")] 1562enum TryFromU32 { 1563 One, 1564 Two, 1565} 1566 1567impl TryFrom<u32> for TryFromU32 { 1568 type Error = String; 1569 1570 fn try_from(value: u32) -> Result<Self, Self::Error> { 1571 match value { 1572 1 => Ok(TryFromU32::One), 1573 2 => Ok(TryFromU32::Two), 1574 _ => Err("out of range".to_owned()), 1575 } 1576 } 1577} 1578 1579#[test] 1580fn test_from_into_traits() { 1581 assert_ser_tokens(&EnumToU32::One, &[Token::Some, Token::U32(1)]); 1582 assert_ser_tokens(&EnumToU32::Nothing, &[Token::None]); 1583 assert_de_tokens(&EnumToU32::Two, &[Token::Some, Token::U32(2)]); 1584 assert_ser_tokens(&StructFromEnum(Some(5)), &[Token::None]); 1585 assert_ser_tokens(&StructFromEnum(None), &[Token::None]); 1586 assert_de_tokens(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]); 1587 assert_de_tokens(&TryFromU32::Two, &[Token::U32(2)]); 1588 assert_de_tokens_error::<TryFromU32>(&[Token::U32(5)], "out of range"); 1589} 1590 1591#[test] 1592fn test_collect_other() { 1593 let mut extra = HashMap::new(); 1594 extra.insert("c".into(), 3); 1595 assert_tokens( 1596 &CollectOther { a: 1, b: 2, extra }, 1597 &[ 1598 Token::Map { len: None }, 1599 Token::Str("a"), 1600 Token::U32(1), 1601 Token::Str("b"), 1602 Token::U32(2), 1603 Token::Str("c"), 1604 Token::U32(3), 1605 Token::MapEnd, 1606 ], 1607 ); 1608} 1609 1610#[test] 1611fn test_unknown_field_in_flatten() { 1612 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1613 #[serde(deny_unknown_fields)] 1614 struct Outer { 1615 dummy: String, 1616 #[serde(flatten)] 1617 inner: Inner, 1618 } 1619 1620 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1621 struct Inner { 1622 foo: HashMap<String, u32>, 1623 } 1624 1625 assert_de_tokens_error::<Outer>( 1626 &[ 1627 Token::Struct { 1628 name: "Outer", 1629 len: 1, 1630 }, 1631 Token::Str("dummy"), 1632 Token::Str("23"), 1633 Token::Str("foo"), 1634 Token::Map { len: None }, 1635 Token::Str("a"), 1636 Token::U32(1), 1637 Token::Str("b"), 1638 Token::U32(2), 1639 Token::MapEnd, 1640 Token::Str("bar"), 1641 Token::U32(23), 1642 Token::StructEnd, 1643 ], 1644 "unknown field `bar`", 1645 ); 1646} 1647 1648#[test] 1649fn test_complex_flatten() { 1650 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1651 struct Outer { 1652 y: u32, 1653 #[serde(flatten)] 1654 first: First, 1655 #[serde(flatten)] 1656 second: Second, 1657 z: u32, 1658 } 1659 1660 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1661 struct First { 1662 a: u32, 1663 b: bool, 1664 c: Vec<String>, 1665 d: String, 1666 e: Option<u64>, 1667 } 1668 1669 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1670 struct Second { 1671 f: u32, 1672 } 1673 1674 assert_de_tokens( 1675 &Outer { 1676 y: 0, 1677 first: First { 1678 a: 1, 1679 b: true, 1680 c: vec!["a".into(), "b".into()], 1681 d: "c".into(), 1682 e: Some(2), 1683 }, 1684 second: Second { f: 3 }, 1685 z: 4, 1686 }, 1687 &[ 1688 Token::Map { len: None }, 1689 Token::Str("y"), 1690 Token::U32(0), 1691 Token::Str("a"), 1692 Token::U32(1), 1693 Token::Str("b"), 1694 Token::Bool(true), 1695 Token::Str("c"), 1696 Token::Seq { len: Some(2) }, 1697 Token::Str("a"), 1698 Token::Str("b"), 1699 Token::SeqEnd, 1700 Token::Str("d"), 1701 Token::Str("c"), 1702 Token::Str("e"), 1703 Token::U64(2), 1704 Token::Str("f"), 1705 Token::U32(3), 1706 Token::Str("z"), 1707 Token::U32(4), 1708 Token::MapEnd, 1709 ], 1710 ); 1711 1712 assert_ser_tokens( 1713 &Outer { 1714 y: 0, 1715 first: First { 1716 a: 1, 1717 b: true, 1718 c: vec!["a".into(), "b".into()], 1719 d: "c".into(), 1720 e: Some(2), 1721 }, 1722 second: Second { f: 3 }, 1723 z: 4, 1724 }, 1725 &[ 1726 Token::Map { len: None }, 1727 Token::Str("y"), 1728 Token::U32(0), 1729 Token::Str("a"), 1730 Token::U32(1), 1731 Token::Str("b"), 1732 Token::Bool(true), 1733 Token::Str("c"), 1734 Token::Seq { len: Some(2) }, 1735 Token::Str("a"), 1736 Token::Str("b"), 1737 Token::SeqEnd, 1738 Token::Str("d"), 1739 Token::Str("c"), 1740 Token::Str("e"), 1741 Token::Some, 1742 Token::U64(2), 1743 Token::Str("f"), 1744 Token::U32(3), 1745 Token::Str("z"), 1746 Token::U32(4), 1747 Token::MapEnd, 1748 ], 1749 ); 1750} 1751 1752#[test] 1753fn test_flatten_map_twice() { 1754 #[derive(Debug, PartialEq, Deserialize)] 1755 struct Outer { 1756 #[serde(flatten)] 1757 first: BTreeMap<String, String>, 1758 #[serde(flatten)] 1759 between: Inner, 1760 #[serde(flatten)] 1761 second: BTreeMap<String, String>, 1762 } 1763 1764 #[derive(Debug, PartialEq, Deserialize)] 1765 struct Inner { 1766 y: String, 1767 } 1768 1769 assert_de_tokens( 1770 &Outer { 1771 first: { 1772 let mut first = BTreeMap::new(); 1773 first.insert("x".to_owned(), "X".to_owned()); 1774 first.insert("y".to_owned(), "Y".to_owned()); 1775 first 1776 }, 1777 between: Inner { y: "Y".to_owned() }, 1778 second: { 1779 let mut second = BTreeMap::new(); 1780 second.insert("x".to_owned(), "X".to_owned()); 1781 second 1782 }, 1783 }, 1784 &[ 1785 Token::Map { len: None }, 1786 Token::Str("x"), 1787 Token::Str("X"), 1788 Token::Str("y"), 1789 Token::Str("Y"), 1790 Token::MapEnd, 1791 ], 1792 ); 1793} 1794 1795#[test] 1796fn test_flatten_unit() { 1797 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1798 struct Response<T> { 1799 #[serde(flatten)] 1800 data: T, 1801 status: usize, 1802 } 1803 1804 assert_tokens( 1805 &Response { 1806 data: (), 1807 status: 0, 1808 }, 1809 &[ 1810 Token::Map { len: None }, 1811 Token::Str("status"), 1812 Token::U64(0), 1813 Token::MapEnd, 1814 ], 1815 ); 1816} 1817 1818#[test] 1819fn test_flatten_unsupported_type() { 1820 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1821 struct Outer { 1822 outer: String, 1823 #[serde(flatten)] 1824 inner: String, 1825 } 1826 1827 assert_ser_tokens_error( 1828 &Outer { 1829 outer: "foo".into(), 1830 inner: "bar".into(), 1831 }, 1832 &[ 1833 Token::Map { len: None }, 1834 Token::Str("outer"), 1835 Token::Str("foo"), 1836 ], 1837 "can only flatten structs and maps (got a string)", 1838 ); 1839 assert_de_tokens_error::<Outer>( 1840 &[ 1841 Token::Map { len: None }, 1842 Token::Str("outer"), 1843 Token::Str("foo"), 1844 Token::Str("a"), 1845 Token::Str("b"), 1846 Token::MapEnd, 1847 ], 1848 "can only flatten structs and maps", 1849 ); 1850} 1851 1852#[test] 1853fn test_non_string_keys() { 1854 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1855 struct TestStruct { 1856 name: String, 1857 age: u32, 1858 #[serde(flatten)] 1859 mapping: HashMap<u32, u32>, 1860 } 1861 1862 let mut mapping = HashMap::new(); 1863 mapping.insert(0, 42); 1864 assert_tokens( 1865 &TestStruct { 1866 name: "peter".into(), 1867 age: 3, 1868 mapping, 1869 }, 1870 &[ 1871 Token::Map { len: None }, 1872 Token::Str("name"), 1873 Token::Str("peter"), 1874 Token::Str("age"), 1875 Token::U32(3), 1876 Token::U32(0), 1877 Token::U32(42), 1878 Token::MapEnd, 1879 ], 1880 ); 1881} 1882 1883#[test] 1884fn test_lifetime_propagation_for_flatten() { 1885 #[derive(Deserialize, Serialize, Debug, PartialEq)] 1886 struct A<T> { 1887 #[serde(flatten)] 1888 t: T, 1889 } 1890 1891 #[derive(Deserialize, Serialize, Debug, PartialEq)] 1892 struct B<'a> { 1893 #[serde(flatten, borrow)] 1894 t: HashMap<&'a str, u32>, 1895 } 1896 1897 #[derive(Deserialize, Serialize, Debug, PartialEq)] 1898 struct C<'a> { 1899 #[serde(flatten, borrow)] 1900 t: HashMap<&'a [u8], u32>, 1901 } 1902 1903 let mut owned_map = HashMap::new(); 1904 owned_map.insert("x".to_string(), 42u32); 1905 assert_tokens( 1906 &A { t: owned_map }, 1907 &[ 1908 Token::Map { len: None }, 1909 Token::Str("x"), 1910 Token::U32(42), 1911 Token::MapEnd, 1912 ], 1913 ); 1914 1915 let mut borrowed_map = HashMap::new(); 1916 borrowed_map.insert("x", 42u32); 1917 assert_ser_tokens( 1918 &B { 1919 t: borrowed_map.clone(), 1920 }, 1921 &[ 1922 Token::Map { len: None }, 1923 Token::BorrowedStr("x"), 1924 Token::U32(42), 1925 Token::MapEnd, 1926 ], 1927 ); 1928 1929 assert_de_tokens( 1930 &B { t: borrowed_map }, 1931 &[ 1932 Token::Map { len: None }, 1933 Token::BorrowedStr("x"), 1934 Token::U32(42), 1935 Token::MapEnd, 1936 ], 1937 ); 1938 1939 let mut borrowed_map = HashMap::new(); 1940 borrowed_map.insert(&b"x"[..], 42u32); 1941 assert_ser_tokens( 1942 &C { 1943 t: borrowed_map.clone(), 1944 }, 1945 &[ 1946 Token::Map { len: None }, 1947 Token::Seq { len: Some(1) }, 1948 Token::U8(120), 1949 Token::SeqEnd, 1950 Token::U32(42), 1951 Token::MapEnd, 1952 ], 1953 ); 1954 1955 assert_de_tokens( 1956 &C { t: borrowed_map }, 1957 &[ 1958 Token::Map { len: None }, 1959 Token::BorrowedBytes(b"x"), 1960 Token::U32(42), 1961 Token::MapEnd, 1962 ], 1963 ); 1964} 1965 1966#[test] 1967fn test_externally_tagged_enum_containing_flatten() { 1968 #[derive(Serialize, Deserialize, PartialEq, Debug)] 1969 enum Data { 1970 A { 1971 a: i32, 1972 #[serde(flatten)] 1973 flat: Flat, 1974 }, 1975 } 1976 1977 #[derive(Serialize, Deserialize, PartialEq, Debug)] 1978 struct Flat { 1979 b: i32, 1980 } 1981 1982 let data = Data::A { 1983 a: 0, 1984 flat: Flat { b: 0 }, 1985 }; 1986 1987 assert_tokens( 1988 &data, 1989 &[ 1990 Token::NewtypeVariant { 1991 name: "Data", 1992 variant: "A", 1993 }, 1994 Token::Map { len: None }, 1995 Token::Str("a"), 1996 Token::I32(0), 1997 Token::Str("b"), 1998 Token::I32(0), 1999 Token::MapEnd, 2000 ], 2001 ); 2002} 2003 2004#[test] 2005fn test_internally_tagged_enum_with_skipped_conflict() { 2006 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2007 #[serde(tag = "t")] 2008 enum Data { 2009 A, 2010 #[serde(skip)] 2011 #[allow(dead_code)] 2012 B { 2013 t: String, 2014 }, 2015 C { 2016 #[serde(default, skip)] 2017 t: String, 2018 }, 2019 } 2020 2021 let data = Data::C { t: String::new() }; 2022 2023 assert_tokens( 2024 &data, 2025 &[ 2026 Token::Struct { 2027 name: "Data", 2028 len: 1, 2029 }, 2030 Token::Str("t"), 2031 Token::Str("C"), 2032 Token::StructEnd, 2033 ], 2034 ); 2035} 2036 2037#[test] 2038fn test_internally_tagged_enum_containing_flatten() { 2039 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2040 #[serde(tag = "t")] 2041 enum Data { 2042 A { 2043 a: i32, 2044 #[serde(flatten)] 2045 flat: Flat, 2046 }, 2047 } 2048 2049 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2050 struct Flat { 2051 b: i32, 2052 } 2053 2054 let data = Data::A { 2055 a: 0, 2056 flat: Flat { b: 0 }, 2057 }; 2058 2059 assert_tokens( 2060 &data, 2061 &[ 2062 Token::Map { len: None }, 2063 Token::Str("t"), 2064 Token::Str("A"), 2065 Token::Str("a"), 2066 Token::I32(0), 2067 Token::Str("b"), 2068 Token::I32(0), 2069 Token::MapEnd, 2070 ], 2071 ); 2072} 2073 2074#[test] 2075fn test_internally_tagged_enum_new_type_with_unit() { 2076 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2077 #[serde(tag = "t")] 2078 enum Data { 2079 A(()), 2080 } 2081 2082 assert_tokens( 2083 &Data::A(()), 2084 &[ 2085 Token::Map { len: Some(1) }, 2086 Token::Str("t"), 2087 Token::Str("A"), 2088 Token::MapEnd, 2089 ], 2090 ); 2091} 2092 2093#[test] 2094fn test_adjacently_tagged_enum_bytes() { 2095 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2096 #[serde(tag = "t", content = "c")] 2097 enum Data { 2098 A { a: i32 }, 2099 } 2100 2101 let data = Data::A { a: 0 }; 2102 2103 assert_tokens( 2104 &data, 2105 &[ 2106 Token::Struct { 2107 name: "Data", 2108 len: 2, 2109 }, 2110 Token::Str("t"), 2111 Token::UnitVariant { 2112 name: "Data", 2113 variant: "A", 2114 }, 2115 Token::Str("c"), 2116 Token::Struct { name: "A", len: 1 }, 2117 Token::Str("a"), 2118 Token::I32(0), 2119 Token::StructEnd, 2120 Token::StructEnd, 2121 ], 2122 ); 2123 2124 assert_de_tokens( 2125 &data, 2126 &[ 2127 Token::Struct { 2128 name: "Data", 2129 len: 2, 2130 }, 2131 Token::Bytes(b"t"), 2132 Token::UnitVariant { 2133 name: "Data", 2134 variant: "A", 2135 }, 2136 Token::Bytes(b"c"), 2137 Token::Struct { name: "A", len: 1 }, 2138 Token::Str("a"), 2139 Token::I32(0), 2140 Token::StructEnd, 2141 Token::StructEnd, 2142 ], 2143 ); 2144} 2145 2146#[test] 2147fn test_adjacently_tagged_enum_containing_flatten() { 2148 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2149 #[serde(tag = "t", content = "c")] 2150 enum Data { 2151 A { 2152 a: i32, 2153 #[serde(flatten)] 2154 flat: Flat, 2155 }, 2156 } 2157 2158 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2159 struct Flat { 2160 b: i32, 2161 } 2162 2163 let data = Data::A { 2164 a: 0, 2165 flat: Flat { b: 0 }, 2166 }; 2167 2168 assert_tokens( 2169 &data, 2170 &[ 2171 Token::Struct { 2172 name: "Data", 2173 len: 2, 2174 }, 2175 Token::Str("t"), 2176 Token::UnitVariant { 2177 name: "Data", 2178 variant: "A", 2179 }, 2180 Token::Str("c"), 2181 Token::Map { len: None }, 2182 Token::Str("a"), 2183 Token::I32(0), 2184 Token::Str("b"), 2185 Token::I32(0), 2186 Token::MapEnd, 2187 Token::StructEnd, 2188 ], 2189 ); 2190} 2191 2192#[test] 2193fn test_untagged_enum_containing_flatten() { 2194 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2195 #[serde(untagged)] 2196 enum Data { 2197 A { 2198 a: i32, 2199 #[serde(flatten)] 2200 flat: Flat, 2201 }, 2202 } 2203 2204 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2205 struct Flat { 2206 b: i32, 2207 } 2208 2209 let data = Data::A { 2210 a: 0, 2211 flat: Flat { b: 0 }, 2212 }; 2213 2214 assert_tokens( 2215 &data, 2216 &[ 2217 Token::Map { len: None }, 2218 Token::Str("a"), 2219 Token::I32(0), 2220 Token::Str("b"), 2221 Token::I32(0), 2222 Token::MapEnd, 2223 ], 2224 ); 2225} 2226 2227#[test] 2228fn test_partially_untagged_enum() { 2229 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2230 enum Exp { 2231 Lambda(u32, Box<Exp>), 2232 #[serde(untagged)] 2233 App(Box<Exp>, Box<Exp>), 2234 #[serde(untagged)] 2235 Var(u32), 2236 } 2237 use Exp::*; 2238 2239 let data = Lambda(0, Box::new(App(Box::new(Var(0)), Box::new(Var(0))))); 2240 assert_tokens( 2241 &data, 2242 &[ 2243 Token::TupleVariant { 2244 name: "Exp", 2245 variant: "Lambda", 2246 len: 2, 2247 }, 2248 Token::U32(0), 2249 Token::Tuple { len: 2 }, 2250 Token::U32(0), 2251 Token::U32(0), 2252 Token::TupleEnd, 2253 Token::TupleVariantEnd, 2254 ], 2255 ); 2256} 2257 2258#[test] 2259fn test_partially_untagged_enum_generic() { 2260 trait Trait<T> { 2261 type Assoc; 2262 type Assoc2; 2263 } 2264 2265 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2266 enum E<A, B, C> 2267 where 2268 A: Trait<C, Assoc2 = B>, 2269 { 2270 A(A::Assoc), 2271 #[serde(untagged)] 2272 B(A::Assoc2), 2273 } 2274 2275 impl<T> Trait<T> for () { 2276 type Assoc = T; 2277 type Assoc2 = bool; 2278 } 2279 2280 type MyE = E<(), bool, u32>; 2281 use E::*; 2282 2283 assert_tokens::<MyE>(&B(true), &[Token::Bool(true)]); 2284 2285 assert_tokens::<MyE>( 2286 &A(5), 2287 &[ 2288 Token::NewtypeVariant { 2289 name: "E", 2290 variant: "A", 2291 }, 2292 Token::U32(5), 2293 ], 2294 ); 2295} 2296 2297#[test] 2298fn test_partially_untagged_enum_desugared() { 2299 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2300 enum Test { 2301 A(u32, u32), 2302 B(u32), 2303 #[serde(untagged)] 2304 C(u32), 2305 #[serde(untagged)] 2306 D(u32, u32), 2307 } 2308 use Test::*; 2309 2310 mod desugared { 2311 use super::*; 2312 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2313 pub(super) enum Test { 2314 A(u32, u32), 2315 B(u32), 2316 } 2317 } 2318 use desugared::Test as TestTagged; 2319 2320 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2321 #[serde(untagged)] 2322 enum TestUntagged { 2323 Tagged(TestTagged), 2324 C(u32), 2325 D(u32, u32), 2326 } 2327 2328 impl From<Test> for TestUntagged { 2329 fn from(test: Test) -> Self { 2330 match test { 2331 A(x, y) => TestUntagged::Tagged(TestTagged::A(x, y)), 2332 B(x) => TestUntagged::Tagged(TestTagged::B(x)), 2333 C(x) => TestUntagged::C(x), 2334 D(x, y) => TestUntagged::D(x, y), 2335 } 2336 } 2337 } 2338 2339 fn assert_tokens_desugared(value: Test, tokens: &[Token]) { 2340 assert_tokens(&value, tokens); 2341 let desugared: TestUntagged = value.into(); 2342 assert_tokens(&desugared, tokens); 2343 } 2344 2345 assert_tokens_desugared( 2346 A(0, 1), 2347 &[ 2348 Token::TupleVariant { 2349 name: "Test", 2350 variant: "A", 2351 len: 2, 2352 }, 2353 Token::U32(0), 2354 Token::U32(1), 2355 Token::TupleVariantEnd, 2356 ], 2357 ); 2358 2359 assert_tokens_desugared( 2360 B(1), 2361 &[ 2362 Token::NewtypeVariant { 2363 name: "Test", 2364 variant: "B", 2365 }, 2366 Token::U32(1), 2367 ], 2368 ); 2369 2370 assert_tokens_desugared(C(2), &[Token::U32(2)]); 2371 2372 assert_tokens_desugared( 2373 D(3, 5), 2374 &[ 2375 Token::Tuple { len: 2 }, 2376 Token::U32(3), 2377 Token::U32(5), 2378 Token::TupleEnd, 2379 ], 2380 ); 2381} 2382 2383#[test] 2384fn test_partially_untagged_internally_tagged_enum() { 2385 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2386 #[serde(tag = "t")] 2387 enum Data { 2388 A, 2389 B, 2390 #[serde(untagged)] 2391 Var(u32), 2392 } 2393 2394 let data = Data::A; 2395 2396 assert_de_tokens( 2397 &data, 2398 &[ 2399 Token::Map { len: None }, 2400 Token::Str("t"), 2401 Token::Str("A"), 2402 Token::MapEnd, 2403 ], 2404 ); 2405 2406 let data = Data::Var(42); 2407 2408 assert_de_tokens(&data, &[Token::U32(42)]); 2409 2410 // TODO test error output 2411} 2412 2413#[test] 2414fn test_partially_untagged_adjacently_tagged_enum() { 2415 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2416 #[serde(tag = "t", content = "c")] 2417 enum Data { 2418 A(u32), 2419 B, 2420 #[serde(untagged)] 2421 Var(u32), 2422 } 2423 2424 let data = Data::A(7); 2425 2426 assert_de_tokens( 2427 &data, 2428 &[ 2429 Token::Map { len: None }, 2430 Token::Str("t"), 2431 Token::Str("A"), 2432 Token::Str("c"), 2433 Token::U32(7), 2434 Token::MapEnd, 2435 ], 2436 ); 2437 2438 let data = Data::Var(42); 2439 2440 assert_de_tokens(&data, &[Token::U32(42)]); 2441 2442 // TODO test error output 2443} 2444 2445#[test] 2446fn test_flatten_option() { 2447 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2448 struct Outer { 2449 #[serde(flatten)] 2450 inner1: Option<Inner1>, 2451 #[serde(flatten)] 2452 inner2: Option<Inner2>, 2453 } 2454 2455 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2456 struct Inner1 { 2457 inner1: i32, 2458 } 2459 2460 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2461 struct Inner2 { 2462 inner2: i32, 2463 } 2464 2465 assert_tokens( 2466 &Outer { 2467 inner1: Some(Inner1 { inner1: 1 }), 2468 inner2: Some(Inner2 { inner2: 2 }), 2469 }, 2470 &[ 2471 Token::Map { len: None }, 2472 Token::Str("inner1"), 2473 Token::I32(1), 2474 Token::Str("inner2"), 2475 Token::I32(2), 2476 Token::MapEnd, 2477 ], 2478 ); 2479 2480 assert_tokens( 2481 &Outer { 2482 inner1: Some(Inner1 { inner1: 1 }), 2483 inner2: None, 2484 }, 2485 &[ 2486 Token::Map { len: None }, 2487 Token::Str("inner1"), 2488 Token::I32(1), 2489 Token::MapEnd, 2490 ], 2491 ); 2492 2493 assert_tokens( 2494 &Outer { 2495 inner1: None, 2496 inner2: Some(Inner2 { inner2: 2 }), 2497 }, 2498 &[ 2499 Token::Map { len: None }, 2500 Token::Str("inner2"), 2501 Token::I32(2), 2502 Token::MapEnd, 2503 ], 2504 ); 2505 2506 assert_tokens( 2507 &Outer { 2508 inner1: None, 2509 inner2: None, 2510 }, 2511 &[Token::Map { len: None }, Token::MapEnd], 2512 ); 2513} 2514 2515#[test] 2516fn test_flatten_ignored_any() { 2517 #[derive(Deserialize, PartialEq, Debug)] 2518 struct Outer { 2519 #[serde(flatten)] 2520 inner: IgnoredAny, 2521 } 2522 2523 assert_de_tokens( 2524 &Outer { inner: IgnoredAny }, 2525 &[Token::Map { len: None }, Token::MapEnd], 2526 ); 2527 2528 assert_de_tokens( 2529 &Outer { inner: IgnoredAny }, 2530 &[ 2531 Token::Struct { 2532 name: "DoNotMatter", 2533 len: 0, 2534 }, 2535 Token::StructEnd, 2536 ], 2537 ); 2538} 2539 2540#[test] 2541fn test_transparent_struct() { 2542 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2543 #[serde(transparent)] 2544 struct Transparent { 2545 #[serde(skip)] 2546 a: bool, 2547 b: u32, 2548 #[serde(skip)] 2549 c: bool, 2550 d: PhantomData<()>, 2551 } 2552 2553 assert_tokens( 2554 &Transparent { 2555 a: false, 2556 b: 1, 2557 c: false, 2558 d: PhantomData, 2559 }, 2560 &[Token::U32(1)], 2561 ); 2562} 2563 2564#[test] 2565fn test_transparent_tuple_struct() { 2566 #[derive(Serialize, Deserialize, PartialEq, Debug)] 2567 #[serde(transparent)] 2568 struct Transparent( 2569 #[serde(skip)] bool, 2570 u32, 2571 #[serde(skip)] bool, 2572 PhantomData<()>, 2573 ); 2574 2575 assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]); 2576} 2577 2578#[test] 2579fn test_internally_tagged_unit_enum_with_unknown_fields() { 2580 #[derive(Deserialize, PartialEq, Debug)] 2581 #[serde(tag = "t")] 2582 enum Data { 2583 A, 2584 } 2585 2586 let data = Data::A; 2587 2588 assert_de_tokens( 2589 &data, 2590 &[ 2591 Token::Map { len: None }, 2592 Token::Str("t"), 2593 Token::Str("A"), 2594 Token::Str("b"), 2595 Token::I32(0), 2596 Token::MapEnd, 2597 ], 2598 ); 2599} 2600 2601#[test] 2602fn test_flatten_any_after_flatten_struct() { 2603 #[derive(PartialEq, Debug)] 2604 struct Any; 2605 2606 impl<'de> Deserialize<'de> for Any { 2607 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 2608 where 2609 D: Deserializer<'de>, 2610 { 2611 struct AnyVisitor; 2612 2613 impl<'de> Visitor<'de> for AnyVisitor { 2614 type Value = Any; 2615 2616 fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { 2617 unimplemented!() 2618 } 2619 2620 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error> 2621 where 2622 M: MapAccess<'de>, 2623 { 2624 while let Some((Any, Any)) = map.next_entry()? {} 2625 Ok(Any) 2626 } 2627 } 2628 2629 deserializer.deserialize_any(AnyVisitor) 2630 } 2631 } 2632 2633 #[derive(Deserialize, PartialEq, Debug)] 2634 struct Outer { 2635 #[serde(flatten)] 2636 inner: Inner, 2637 #[serde(flatten)] 2638 extra: Any, 2639 } 2640 2641 #[derive(Deserialize, PartialEq, Debug)] 2642 struct Inner { 2643 inner: i32, 2644 } 2645 2646 let s = Outer { 2647 inner: Inner { inner: 0 }, 2648 extra: Any, 2649 }; 2650 2651 assert_de_tokens( 2652 &s, 2653 &[ 2654 Token::Map { len: None }, 2655 Token::Str("inner"), 2656 Token::I32(0), 2657 Token::MapEnd, 2658 ], 2659 ); 2660} 2661 2662#[test] 2663fn test_alias_in_flatten_context() { 2664 #[derive(Debug, PartialEq, Deserialize)] 2665 struct Outer { 2666 #[serde(flatten)] 2667 a: AliasStruct, 2668 b: i32, 2669 } 2670 2671 assert_de_tokens( 2672 &Outer { 2673 a: AliasStruct { 2674 a1: 1, 2675 a2: 2, 2676 a4: 4, 2677 }, 2678 b: 7, 2679 }, 2680 &[ 2681 Token::Struct { 2682 name: "Outer", 2683 len: 4, 2684 }, 2685 Token::Str("a1"), 2686 Token::I32(1), 2687 Token::Str("a2"), 2688 Token::I32(2), 2689 Token::Str("a5"), 2690 Token::I32(4), 2691 Token::Str("b"), 2692 Token::I32(7), 2693 Token::StructEnd, 2694 ], 2695 ); 2696 2697 assert_de_tokens( 2698 &Outer { 2699 a: AliasStruct { 2700 a1: 1, 2701 a2: 2, 2702 a4: 4, 2703 }, 2704 b: 7, 2705 }, 2706 &[ 2707 Token::Struct { 2708 name: "Outer", 2709 len: 4, 2710 }, 2711 Token::Str("a1"), 2712 Token::I32(1), 2713 Token::Str("a2"), 2714 Token::I32(2), 2715 Token::Str("a6"), 2716 Token::I32(4), 2717 Token::Str("b"), 2718 Token::I32(7), 2719 Token::StructEnd, 2720 ], 2721 ); 2722} 2723 2724#[test] 2725fn test_expecting_message() { 2726 #[derive(Deserialize, PartialEq, Debug)] 2727 #[serde(expecting = "something strange...")] 2728 struct Unit; 2729 2730 #[derive(Deserialize)] 2731 #[serde(expecting = "something strange...")] 2732 struct Newtype(bool); 2733 2734 #[derive(Deserialize)] 2735 #[serde(expecting = "something strange...")] 2736 struct Tuple(u32, bool); 2737 2738 #[derive(Deserialize)] 2739 #[serde(expecting = "something strange...")] 2740 struct Struct { 2741 #[allow(dead_code)] 2742 question: String, 2743 #[allow(dead_code)] 2744 answer: u32, 2745 } 2746 2747 assert_de_tokens_error::<Unit>( 2748 &[Token::Str("Unit")], 2749 r#"invalid type: string "Unit", expected something strange..."#, 2750 ); 2751 2752 assert_de_tokens_error::<Newtype>( 2753 &[Token::Str("Newtype")], 2754 r#"invalid type: string "Newtype", expected something strange..."#, 2755 ); 2756 2757 assert_de_tokens_error::<Tuple>( 2758 &[Token::Str("Tuple")], 2759 r#"invalid type: string "Tuple", expected something strange..."#, 2760 ); 2761 2762 assert_de_tokens_error::<Struct>( 2763 &[Token::Str("Struct")], 2764 r#"invalid type: string "Struct", expected something strange..."#, 2765 ); 2766} 2767 2768#[test] 2769fn test_expecting_message_externally_tagged_enum() { 2770 #[derive(Deserialize)] 2771 #[serde(expecting = "something strange...")] 2772 enum Enum { 2773 ExternallyTagged, 2774 } 2775 2776 assert_de_tokens_error::<Enum>( 2777 &[Token::Str("ExternallyTagged")], 2778 r#"invalid type: string "ExternallyTagged", expected something strange..."#, 2779 ); 2780 2781 // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message 2782 assert_de_tokens_error::<Enum>( 2783 &[Token::Enum { name: "Enum" }, Token::Unit], 2784 "invalid type: unit value, expected variant identifier", 2785 ); 2786} 2787 2788#[test] 2789fn test_expecting_message_internally_tagged_enum() { 2790 #[derive(Deserialize)] 2791 #[serde(tag = "tag")] 2792 #[serde(expecting = "something strange...")] 2793 enum Enum { 2794 InternallyTagged, 2795 } 2796 2797 assert_de_tokens_error::<Enum>( 2798 &[Token::Str("InternallyTagged")], 2799 r#"invalid type: string "InternallyTagged", expected something strange..."#, 2800 ); 2801 2802 // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message 2803 assert_de_tokens_error::<Enum>( 2804 &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], 2805 "invalid type: unit value, expected variant identifier", 2806 ); 2807} 2808 2809#[test] 2810fn test_expecting_message_adjacently_tagged_enum() { 2811 #[derive(Deserialize)] 2812 #[serde(tag = "tag", content = "content")] 2813 #[serde(expecting = "something strange...")] 2814 enum Enum { 2815 AdjacentlyTagged, 2816 } 2817 2818 assert_de_tokens_error::<Enum>( 2819 &[Token::Str("AdjacentlyTagged")], 2820 r#"invalid type: string "AdjacentlyTagged", expected something strange..."#, 2821 ); 2822 2823 assert_de_tokens_error::<Enum>( 2824 &[Token::Map { len: None }, Token::Unit], 2825 r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#, 2826 ); 2827 2828 // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message 2829 assert_de_tokens_error::<Enum>( 2830 &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], 2831 "invalid type: unit value, expected variant of enum Enum", 2832 ); 2833} 2834 2835#[test] 2836fn test_expecting_message_untagged_tagged_enum() { 2837 #[derive(Deserialize)] 2838 #[serde(untagged)] 2839 #[serde(expecting = "something strange...")] 2840 enum Enum { 2841 Untagged, 2842 } 2843 2844 assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], "something strange..."); 2845} 2846 2847#[test] 2848fn test_expecting_message_identifier_enum() { 2849 #[derive(Deserialize)] 2850 #[serde(field_identifier)] 2851 #[serde(expecting = "something strange...")] 2852 enum FieldEnum { 2853 Field, 2854 } 2855 2856 #[derive(Deserialize)] 2857 #[serde(variant_identifier)] 2858 #[serde(expecting = "something strange...")] 2859 enum VariantEnum { 2860 Variant, 2861 } 2862 2863 assert_de_tokens_error::<FieldEnum>( 2864 &[Token::Unit], 2865 "invalid type: unit value, expected something strange...", 2866 ); 2867 2868 assert_de_tokens_error::<FieldEnum>( 2869 &[ 2870 Token::Enum { name: "FieldEnum" }, 2871 Token::Str("Unknown"), 2872 Token::None, 2873 ], 2874 "invalid type: map, expected something strange...", 2875 ); 2876 2877 assert_de_tokens_error::<VariantEnum>( 2878 &[Token::Unit], 2879 "invalid type: unit value, expected something strange...", 2880 ); 2881 2882 assert_de_tokens_error::<VariantEnum>( 2883 &[ 2884 Token::Enum { 2885 name: "VariantEnum", 2886 }, 2887 Token::Str("Unknown"), 2888 Token::None, 2889 ], 2890 "invalid type: map, expected something strange...", 2891 ); 2892} 2893 2894mod flatten { 2895 use super::*; 2896 2897 mod enum_ { 2898 use super::*; 2899 2900 mod externally_tagged { 2901 use super::*; 2902 use std::iter::FromIterator; 2903 2904 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2905 struct Flatten { 2906 #[serde(flatten)] 2907 data: Enum, 2908 2909 #[serde(flatten)] 2910 extra: HashMap<String, String>, 2911 } 2912 2913 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2914 enum Enum { 2915 Newtype(HashMap<String, String>), 2916 Tuple(u32, u32), 2917 Struct { index: u32, value: u32 }, 2918 } 2919 2920 #[test] 2921 fn newtype() { 2922 assert_tokens( 2923 &Flatten { 2924 data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])), 2925 extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), 2926 }, 2927 &[ 2928 Token::Map { len: None }, 2929 Token::Str("Newtype"), // variant 2930 Token::Map { len: Some(1) }, 2931 Token::Str("key"), 2932 Token::Str("value"), 2933 Token::MapEnd, 2934 Token::Str("extra_key"), 2935 Token::Str("extra value"), 2936 Token::MapEnd, 2937 ], 2938 ); 2939 } 2940 2941 // Reaches crate::private::de::content::VariantDeserializer::tuple_variant 2942 // Content::Seq case 2943 // via FlatMapDeserializer::deserialize_enum 2944 #[test] 2945 fn tuple() { 2946 assert_tokens( 2947 &Flatten { 2948 data: Enum::Tuple(0, 42), 2949 extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), 2950 }, 2951 &[ 2952 Token::Map { len: None }, 2953 Token::Str("Tuple"), // variant 2954 Token::Seq { len: Some(2) }, 2955 Token::U32(0), 2956 Token::U32(42), 2957 Token::SeqEnd, 2958 Token::Str("extra_key"), 2959 Token::Str("extra value"), 2960 Token::MapEnd, 2961 ], 2962 ); 2963 } 2964 2965 // Reaches crate::private::de::content::VariantDeserializer::struct_variant 2966 // Content::Seq case 2967 // via FlatMapDeserializer::deserialize_enum 2968 #[test] 2969 fn struct_from_seq() { 2970 assert_de_tokens( 2971 &Flatten { 2972 data: Enum::Struct { 2973 index: 0, 2974 value: 42, 2975 }, 2976 extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), 2977 }, 2978 &[ 2979 Token::Map { len: None }, 2980 Token::Str("Struct"), // variant 2981 Token::Seq { len: Some(2) }, 2982 Token::U32(0), // index 2983 Token::U32(42), // value 2984 Token::SeqEnd, 2985 Token::Str("extra_key"), 2986 Token::Str("extra value"), 2987 Token::MapEnd, 2988 ], 2989 ); 2990 } 2991 2992 // Reaches crate::private::de::content::VariantDeserializer::struct_variant 2993 // Content::Map case 2994 // via FlatMapDeserializer::deserialize_enum 2995 #[test] 2996 fn struct_from_map() { 2997 assert_tokens( 2998 &Flatten { 2999 data: Enum::Struct { 3000 index: 0, 3001 value: 42, 3002 }, 3003 extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), 3004 }, 3005 &[ 3006 Token::Map { len: None }, 3007 Token::Str("Struct"), // variant 3008 Token::Struct { 3009 len: 2, 3010 name: "Struct", 3011 }, 3012 Token::Str("index"), 3013 Token::U32(0), 3014 Token::Str("value"), 3015 Token::U32(42), 3016 Token::StructEnd, 3017 Token::Str("extra_key"), 3018 Token::Str("extra value"), 3019 Token::MapEnd, 3020 ], 3021 ); 3022 } 3023 } 3024 3025 mod adjacently_tagged { 3026 use super::*; 3027 3028 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3029 struct Flatten { 3030 outer: u32, 3031 3032 #[serde(flatten)] 3033 data: NewtypeWrapper, 3034 } 3035 3036 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3037 struct NewtypeWrapper(pub Enum); 3038 3039 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3040 #[serde(tag = "tag", content = "content")] 3041 enum Enum { 3042 Newtype(NewtypeVariant), 3043 Struct { index: u32, value: u32 }, 3044 } 3045 3046 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3047 struct NewtypeVariant { 3048 value: u32, 3049 } 3050 3051 #[test] 3052 fn struct_() { 3053 assert_tokens( 3054 &Flatten { 3055 outer: 42, 3056 data: NewtypeWrapper(Enum::Struct { 3057 index: 0, 3058 value: 42, 3059 }), 3060 }, 3061 &[ 3062 Token::Map { len: None }, 3063 Token::Str("outer"), 3064 Token::U32(42), 3065 Token::Str("tag"), 3066 Token::UnitVariant { 3067 name: "Enum", 3068 variant: "Struct", 3069 }, 3070 Token::Str("content"), 3071 Token::Struct { 3072 len: 2, 3073 name: "Struct", 3074 }, 3075 Token::Str("index"), 3076 Token::U32(0), 3077 Token::Str("value"), 3078 Token::U32(42), 3079 Token::StructEnd, 3080 Token::MapEnd, 3081 ], 3082 ); 3083 } 3084 3085 #[test] 3086 fn newtype() { 3087 assert_tokens( 3088 &Flatten { 3089 outer: 42, 3090 data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), 3091 }, 3092 &[ 3093 Token::Map { len: None }, 3094 Token::Str("outer"), 3095 Token::U32(42), 3096 Token::Str("tag"), 3097 Token::UnitVariant { 3098 name: "Enum", 3099 variant: "Newtype", 3100 }, 3101 Token::Str("content"), 3102 Token::Struct { 3103 len: 1, 3104 name: "NewtypeVariant", 3105 }, 3106 Token::Str("value"), 3107 Token::U32(23), 3108 Token::StructEnd, 3109 Token::MapEnd, 3110 ], 3111 ); 3112 } 3113 } 3114 3115 mod internally_tagged { 3116 use super::*; 3117 3118 #[test] 3119 fn structs() { 3120 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3121 struct Flatten { 3122 #[serde(flatten)] 3123 x: X, 3124 #[serde(flatten)] 3125 y: Y, 3126 } 3127 3128 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3129 #[serde(tag = "typeX")] 3130 enum X { 3131 A { a: i32 }, 3132 B { b: i32 }, 3133 } 3134 3135 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3136 #[serde(tag = "typeY")] 3137 enum Y { 3138 C { c: i32 }, 3139 D { d: i32 }, 3140 } 3141 3142 assert_tokens( 3143 &Flatten { 3144 x: X::B { b: 1 }, 3145 y: Y::D { d: 2 }, 3146 }, 3147 &[ 3148 Token::Map { len: None }, 3149 Token::Str("typeX"), 3150 Token::Str("B"), 3151 Token::Str("b"), 3152 Token::I32(1), 3153 Token::Str("typeY"), 3154 Token::Str("D"), 3155 Token::Str("d"), 3156 Token::I32(2), 3157 Token::MapEnd, 3158 ], 3159 ); 3160 } 3161 3162 #[test] 3163 fn unit_enum_with_unknown_fields() { 3164 #[derive(Debug, PartialEq, Deserialize)] 3165 struct Flatten { 3166 #[serde(flatten)] 3167 x: X, 3168 #[serde(flatten)] 3169 y: Y, 3170 } 3171 3172 #[derive(Debug, PartialEq, Deserialize)] 3173 #[serde(tag = "typeX")] 3174 enum X { 3175 A, 3176 } 3177 3178 #[derive(Debug, PartialEq, Deserialize)] 3179 #[serde(tag = "typeY")] 3180 enum Y { 3181 B { c: u32 }, 3182 } 3183 3184 assert_de_tokens( 3185 &Flatten { 3186 x: X::A, 3187 y: Y::B { c: 0 }, 3188 }, 3189 &[ 3190 Token::Map { len: None }, 3191 Token::Str("typeX"), 3192 Token::Str("A"), 3193 Token::Str("typeY"), 3194 Token::Str("B"), 3195 Token::Str("c"), 3196 Token::I32(0), 3197 Token::MapEnd, 3198 ], 3199 ); 3200 } 3201 } 3202 3203 mod untagged { 3204 use super::*; 3205 3206 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3207 struct Flatten { 3208 #[serde(flatten)] 3209 data: Enum, 3210 } 3211 3212 #[derive(Debug, PartialEq, Serialize, Deserialize)] 3213 #[serde(untagged)] 3214 enum Enum { 3215 Struct { a: i32 }, 3216 } 3217 3218 #[test] 3219 fn struct_() { 3220 assert_tokens( 3221 &Flatten { 3222 data: Enum::Struct { a: 0 }, 3223 }, 3224 &[ 3225 Token::Map { len: None }, 3226 Token::Str("a"), 3227 Token::I32(0), 3228 Token::MapEnd, 3229 ], 3230 ); 3231 } 3232 } 3233 } 3234} 3235