1#![deny(trivial_numeric_casts)] 2#![allow( 3 clippy::derive_partial_eq_without_eq, 4 clippy::enum_variant_names, 5 clippy::redundant_field_names, 6 clippy::too_many_lines 7)] 8 9mod bytes; 10 11use serde_derive::{Deserialize, Serialize}; 12use serde_test::{ 13 assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token, 14}; 15use std::collections::BTreeMap; 16use std::marker::PhantomData; 17 18// That tests that the derived Serialize implementation doesn't trigger 19// any warning about `serializer` not being used, in case of empty enums. 20#[derive(Serialize)] 21#[allow(dead_code)] 22#[deny(unused_variables)] 23enum Void {} 24 25#[derive(Debug, PartialEq, Serialize, Deserialize)] 26struct NamedUnit; 27 28#[derive(Debug, PartialEq, Serialize)] 29struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C); 30 31#[derive(Debug, PartialEq, Deserialize)] 32struct DeNamedTuple<A, B, C>(A, B, C); 33 34#[derive(Debug, PartialEq, Serialize)] 35struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> { 36 a: &'a A, 37 b: &'b mut B, 38 c: C, 39} 40 41#[derive(Debug, PartialEq, Deserialize)] 42struct DeNamedMap<A, B, C> { 43 a: A, 44 b: B, 45 c: C, 46} 47 48#[derive(Debug, PartialEq, Serialize)] 49enum SerEnum<'a, B: 'a, C: 'a, D> 50where 51 D: 'a, 52{ 53 Unit, 54 Seq(i8, B, &'a C, &'a mut D), 55 Map { a: i8, b: B, c: &'a C, d: &'a mut D }, 56 57 // Make sure we can support more than one variant. 58 _Unit2, 59 _Seq2(i8, B, &'a C, &'a mut D), 60 _Map2 { a: i8, b: B, c: &'a C, d: &'a mut D }, 61} 62 63#[derive(Debug, PartialEq, Serialize, Deserialize)] 64enum DeEnum<B, C, D> { 65 Unit, 66 Seq(i8, B, C, D), 67 Map { a: i8, b: B, c: C, d: D }, 68 69 // Make sure we can support more than one variant. 70 _Unit2, 71 _Seq2(i8, B, C, D), 72 _Map2 { a: i8, b: B, c: C, d: D }, 73} 74 75#[derive(Serialize)] 76enum Lifetimes<'a> { 77 LifetimeSeq(&'a i32), 78 NoLifetimeSeq(i32), 79 LifetimeMap { a: &'a i32 }, 80 NoLifetimeMap { a: i32 }, 81} 82 83#[derive(Debug, PartialEq, Serialize, Deserialize)] 84pub struct GenericStruct<T> { 85 x: T, 86} 87 88#[derive(Debug, PartialEq, Serialize, Deserialize)] 89pub struct GenericNewTypeStruct<T>(T); 90 91#[derive(Debug, PartialEq, Serialize, Deserialize)] 92pub struct GenericTupleStruct<T, U>(T, U); 93 94#[derive(Debug, PartialEq, Serialize, Deserialize)] 95pub enum GenericEnum<T, U> { 96 Unit, 97 NewType(T), 98 Seq(T, U), 99 Map { x: T, y: U }, 100} 101 102trait AssociatedType { 103 type X; 104} 105 106impl AssociatedType for i32 { 107 type X = i32; 108} 109 110#[derive(Debug, PartialEq, Serialize, Deserialize)] 111struct DefaultTyParam<T: AssociatedType<X = i32> = i32> { 112 phantom: PhantomData<T>, 113} 114 115#[test] 116fn test_named_unit() { 117 assert_tokens(&NamedUnit, &[Token::UnitStruct { name: "NamedUnit" }]); 118} 119 120#[test] 121fn test_ser_named_tuple() { 122 let a = 5; 123 let mut b = 6; 124 let c = 7; 125 assert_ser_tokens( 126 &SerNamedTuple(&a, &mut b, c), 127 &[ 128 Token::TupleStruct { 129 name: "SerNamedTuple", 130 len: 3, 131 }, 132 Token::I32(5), 133 Token::I32(6), 134 Token::I32(7), 135 Token::TupleStructEnd, 136 ], 137 ); 138} 139 140#[test] 141fn test_de_named_tuple() { 142 assert_de_tokens( 143 &DeNamedTuple(5, 6, 7), 144 &[ 145 Token::Seq { len: Some(3) }, 146 Token::I32(5), 147 Token::I32(6), 148 Token::I32(7), 149 Token::SeqEnd, 150 ], 151 ); 152 153 assert_de_tokens( 154 &DeNamedTuple(5, 6, 7), 155 &[ 156 Token::TupleStruct { 157 name: "DeNamedTuple", 158 len: 3, 159 }, 160 Token::I32(5), 161 Token::I32(6), 162 Token::I32(7), 163 Token::TupleStructEnd, 164 ], 165 ); 166} 167 168#[test] 169fn test_ser_named_map() { 170 let a = 5; 171 let mut b = 6; 172 let c = 7; 173 174 assert_ser_tokens( 175 &SerNamedMap { 176 a: &a, 177 b: &mut b, 178 c: c, 179 }, 180 &[ 181 Token::Struct { 182 name: "SerNamedMap", 183 len: 3, 184 }, 185 Token::Str("a"), 186 Token::I32(5), 187 Token::Str("b"), 188 Token::I32(6), 189 Token::Str("c"), 190 Token::I32(7), 191 Token::StructEnd, 192 ], 193 ); 194} 195 196#[test] 197fn test_de_named_map() { 198 assert_de_tokens( 199 &DeNamedMap { a: 5, b: 6, c: 7 }, 200 &[ 201 Token::Struct { 202 name: "DeNamedMap", 203 len: 3, 204 }, 205 Token::Str("a"), 206 Token::I32(5), 207 Token::Str("b"), 208 Token::I32(6), 209 Token::Str("c"), 210 Token::I32(7), 211 Token::StructEnd, 212 ], 213 ); 214} 215 216#[test] 217fn test_ser_enum_unit() { 218 assert_ser_tokens( 219 &SerEnum::Unit::<u32, u32, u32>, 220 &[Token::UnitVariant { 221 name: "SerEnum", 222 variant: "Unit", 223 }], 224 ); 225} 226 227#[test] 228fn test_ser_enum_seq() { 229 let a = 1; 230 let b = 2; 231 let c = 3; 232 let mut d = 4; 233 234 assert_ser_tokens( 235 &SerEnum::Seq(a, b, &c, &mut d), 236 &[ 237 Token::TupleVariant { 238 name: "SerEnum", 239 variant: "Seq", 240 len: 4, 241 }, 242 Token::I8(1), 243 Token::I32(2), 244 Token::I32(3), 245 Token::I32(4), 246 Token::TupleVariantEnd, 247 ], 248 ); 249} 250 251#[test] 252fn test_ser_enum_map() { 253 let a = 1; 254 let b = 2; 255 let c = 3; 256 let mut d = 4; 257 258 assert_ser_tokens( 259 &SerEnum::Map { 260 a: a, 261 b: b, 262 c: &c, 263 d: &mut d, 264 }, 265 &[ 266 Token::StructVariant { 267 name: "SerEnum", 268 variant: "Map", 269 len: 4, 270 }, 271 Token::Str("a"), 272 Token::I8(1), 273 Token::Str("b"), 274 Token::I32(2), 275 Token::Str("c"), 276 Token::I32(3), 277 Token::Str("d"), 278 Token::I32(4), 279 Token::StructVariantEnd, 280 ], 281 ); 282} 283 284#[test] 285fn test_de_enum_unit() { 286 assert_tokens( 287 &DeEnum::Unit::<u32, u32, u32>, 288 &[Token::UnitVariant { 289 name: "DeEnum", 290 variant: "Unit", 291 }], 292 ); 293} 294 295#[test] 296fn test_de_enum_seq() { 297 let a = 1; 298 let b = 2; 299 let c = 3; 300 let d = 4; 301 302 assert_tokens( 303 &DeEnum::Seq(a, b, c, d), 304 &[ 305 Token::TupleVariant { 306 name: "DeEnum", 307 variant: "Seq", 308 len: 4, 309 }, 310 Token::I8(1), 311 Token::I32(2), 312 Token::I32(3), 313 Token::I32(4), 314 Token::TupleVariantEnd, 315 ], 316 ); 317} 318 319#[test] 320fn test_de_enum_map() { 321 let a = 1; 322 let b = 2; 323 let c = 3; 324 let d = 4; 325 326 assert_tokens( 327 &DeEnum::Map { 328 a: a, 329 b: b, 330 c: c, 331 d: d, 332 }, 333 &[ 334 Token::StructVariant { 335 name: "DeEnum", 336 variant: "Map", 337 len: 4, 338 }, 339 Token::Str("a"), 340 Token::I8(1), 341 Token::Str("b"), 342 Token::I32(2), 343 Token::Str("c"), 344 Token::I32(3), 345 Token::Str("d"), 346 Token::I32(4), 347 Token::StructVariantEnd, 348 ], 349 ); 350} 351 352#[test] 353fn test_lifetimes() { 354 let value = 5; 355 356 assert_ser_tokens( 357 &Lifetimes::LifetimeSeq(&value), 358 &[ 359 Token::NewtypeVariant { 360 name: "Lifetimes", 361 variant: "LifetimeSeq", 362 }, 363 Token::I32(5), 364 ], 365 ); 366 367 assert_ser_tokens( 368 &Lifetimes::NoLifetimeSeq(5), 369 &[ 370 Token::NewtypeVariant { 371 name: "Lifetimes", 372 variant: "NoLifetimeSeq", 373 }, 374 Token::I32(5), 375 ], 376 ); 377 378 assert_ser_tokens( 379 &Lifetimes::LifetimeMap { a: &value }, 380 &[ 381 Token::StructVariant { 382 name: "Lifetimes", 383 variant: "LifetimeMap", 384 len: 1, 385 }, 386 Token::Str("a"), 387 Token::I32(5), 388 Token::StructVariantEnd, 389 ], 390 ); 391 392 assert_ser_tokens( 393 &Lifetimes::NoLifetimeMap { a: 5 }, 394 &[ 395 Token::StructVariant { 396 name: "Lifetimes", 397 variant: "NoLifetimeMap", 398 len: 1, 399 }, 400 Token::Str("a"), 401 Token::I32(5), 402 Token::StructVariantEnd, 403 ], 404 ); 405} 406 407#[test] 408fn test_generic_struct() { 409 assert_tokens( 410 &GenericStruct { x: 5u32 }, 411 &[ 412 Token::Struct { 413 name: "GenericStruct", 414 len: 1, 415 }, 416 Token::Str("x"), 417 Token::U32(5), 418 Token::StructEnd, 419 ], 420 ); 421} 422 423#[test] 424fn test_generic_newtype_struct() { 425 assert_tokens( 426 &GenericNewTypeStruct(5u32), 427 &[ 428 Token::NewtypeStruct { 429 name: "GenericNewTypeStruct", 430 }, 431 Token::U32(5), 432 ], 433 ); 434} 435 436#[test] 437fn test_untagged_newtype_struct() { 438 #[derive(Debug, PartialEq, Serialize, Deserialize)] 439 #[serde(untagged)] 440 enum E { 441 Newtype(GenericNewTypeStruct<u32>), 442 Null, 443 } 444 445 assert_tokens( 446 &E::Newtype(GenericNewTypeStruct(5u32)), 447 &[ 448 Token::NewtypeStruct { 449 name: "GenericNewTypeStruct", 450 }, 451 Token::U32(5), 452 ], 453 ); 454} 455 456#[test] 457fn test_adjacently_tagged_newtype_struct() { 458 #[derive(Debug, PartialEq, Serialize, Deserialize)] 459 #[serde(tag = "t", content = "c")] 460 enum E { 461 Newtype(GenericNewTypeStruct<u32>), 462 Null, 463 } 464 465 assert_de_tokens( 466 &E::Newtype(GenericNewTypeStruct(5u32)), 467 &[ 468 Token::Struct { name: "E", len: 2 }, 469 Token::Str("c"), 470 Token::NewtypeStruct { 471 name: "GenericNewTypeStruct", 472 }, 473 Token::U32(5), 474 Token::Str("t"), 475 Token::UnitVariant { 476 name: "E", 477 variant: "Newtype", 478 }, 479 Token::StructEnd, 480 ], 481 ); 482} 483 484#[test] 485fn test_generic_tuple_struct() { 486 assert_tokens( 487 &GenericTupleStruct(5u32, 6u32), 488 &[ 489 Token::TupleStruct { 490 name: "GenericTupleStruct", 491 len: 2, 492 }, 493 Token::U32(5), 494 Token::U32(6), 495 Token::TupleStructEnd, 496 ], 497 ); 498} 499 500#[test] 501fn test_generic_enum_unit() { 502 assert_tokens( 503 &GenericEnum::Unit::<u32, u32>, 504 &[Token::UnitVariant { 505 name: "GenericEnum", 506 variant: "Unit", 507 }], 508 ); 509} 510 511#[test] 512fn test_generic_enum_newtype() { 513 assert_tokens( 514 &GenericEnum::NewType::<u32, u32>(5), 515 &[ 516 Token::NewtypeVariant { 517 name: "GenericEnum", 518 variant: "NewType", 519 }, 520 Token::U32(5), 521 ], 522 ); 523} 524 525#[test] 526fn test_generic_enum_seq() { 527 assert_tokens( 528 &GenericEnum::Seq::<u32, u32>(5, 6), 529 &[ 530 Token::TupleVariant { 531 name: "GenericEnum", 532 variant: "Seq", 533 len: 2, 534 }, 535 Token::U32(5), 536 Token::U32(6), 537 Token::TupleVariantEnd, 538 ], 539 ); 540} 541 542#[test] 543fn test_generic_enum_map() { 544 assert_tokens( 545 &GenericEnum::Map::<u32, u32> { x: 5, y: 6 }, 546 &[ 547 Token::StructVariant { 548 name: "GenericEnum", 549 variant: "Map", 550 len: 2, 551 }, 552 Token::Str("x"), 553 Token::U32(5), 554 Token::Str("y"), 555 Token::U32(6), 556 Token::StructVariantEnd, 557 ], 558 ); 559} 560 561#[test] 562fn test_default_ty_param() { 563 assert_tokens( 564 &DefaultTyParam::<i32> { 565 phantom: PhantomData, 566 }, 567 &[ 568 Token::Struct { 569 name: "DefaultTyParam", 570 len: 1, 571 }, 572 Token::Str("phantom"), 573 Token::UnitStruct { 574 name: "PhantomData", 575 }, 576 Token::StructEnd, 577 ], 578 ); 579} 580 581#[test] 582fn test_enum_state_field() { 583 #[derive(Debug, PartialEq, Serialize, Deserialize)] 584 enum SomeEnum { 585 Key { key: char, state: bool }, 586 } 587 588 assert_tokens( 589 &SomeEnum::Key { 590 key: 'a', 591 state: true, 592 }, 593 &[ 594 Token::StructVariant { 595 name: "SomeEnum", 596 variant: "Key", 597 len: 2, 598 }, 599 Token::Str("key"), 600 Token::Char('a'), 601 Token::Str("state"), 602 Token::Bool(true), 603 Token::StructVariantEnd, 604 ], 605 ); 606} 607 608#[test] 609fn test_untagged_enum() { 610 #[derive(Debug, PartialEq, Serialize, Deserialize)] 611 #[serde(untagged)] 612 enum Untagged { 613 A { a: u8 }, 614 B { b: u8 }, 615 C, 616 D(u8), 617 E(String), 618 F(u8, u8), 619 } 620 621 assert_tokens( 622 &Untagged::A { a: 1 }, 623 &[ 624 Token::Struct { 625 name: "Untagged", 626 len: 1, 627 }, 628 Token::Str("a"), 629 Token::U8(1), 630 Token::StructEnd, 631 ], 632 ); 633 634 assert_tokens( 635 &Untagged::B { b: 2 }, 636 &[ 637 Token::Struct { 638 name: "Untagged", 639 len: 1, 640 }, 641 Token::Str("b"), 642 Token::U8(2), 643 Token::StructEnd, 644 ], 645 ); 646 647 // Serializes to unit, deserializes from either depending on format's 648 // preference. 649 assert_tokens(&Untagged::C, &[Token::Unit]); 650 assert_de_tokens(&Untagged::C, &[Token::None]); 651 652 assert_tokens(&Untagged::D(4), &[Token::U8(4)]); 653 assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]); 654 655 assert_tokens( 656 &Untagged::F(1, 2), 657 &[ 658 Token::Tuple { len: 2 }, 659 Token::U8(1), 660 Token::U8(2), 661 Token::TupleEnd, 662 ], 663 ); 664 665 assert_de_tokens_error::<Untagged>( 666 &[Token::Tuple { len: 1 }, Token::U8(1), Token::TupleEnd], 667 "data did not match any variant of untagged enum Untagged", 668 ); 669 670 assert_de_tokens_error::<Untagged>( 671 &[ 672 Token::Tuple { len: 3 }, 673 Token::U8(1), 674 Token::U8(2), 675 Token::U8(3), 676 Token::TupleEnd, 677 ], 678 "data did not match any variant of untagged enum Untagged", 679 ); 680} 681 682#[test] 683fn test_internally_tagged_enum() { 684 #[derive(Debug, PartialEq, Serialize, Deserialize)] 685 struct Newtype(BTreeMap<String, String>); 686 687 #[derive(Debug, PartialEq, Serialize, Deserialize)] 688 struct Struct { 689 f: u8, 690 } 691 692 #[derive(Debug, PartialEq, Serialize, Deserialize)] 693 #[serde(tag = "type")] 694 enum InternallyTagged { 695 A { a: u8 }, 696 B, 697 C(BTreeMap<String, String>), 698 D(Newtype), 699 E(Struct), 700 } 701 702 assert_tokens( 703 &InternallyTagged::A { a: 1 }, 704 &[ 705 Token::Struct { 706 name: "InternallyTagged", 707 len: 2, 708 }, 709 Token::Str("type"), 710 Token::Str("A"), 711 Token::Str("a"), 712 Token::U8(1), 713 Token::StructEnd, 714 ], 715 ); 716 717 assert_de_tokens( 718 &InternallyTagged::A { a: 1 }, 719 &[ 720 Token::Seq { len: Some(2) }, 721 Token::Str("A"), 722 Token::U8(1), 723 Token::SeqEnd, 724 ], 725 ); 726 727 assert_tokens( 728 &InternallyTagged::B, 729 &[ 730 Token::Struct { 731 name: "InternallyTagged", 732 len: 1, 733 }, 734 Token::Str("type"), 735 Token::Str("B"), 736 Token::StructEnd, 737 ], 738 ); 739 740 assert_de_tokens( 741 &InternallyTagged::B, 742 &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd], 743 ); 744 745 assert_tokens( 746 &InternallyTagged::C(BTreeMap::new()), 747 &[ 748 Token::Map { len: Some(1) }, 749 Token::Str("type"), 750 Token::Str("C"), 751 Token::MapEnd, 752 ], 753 ); 754 755 assert_de_tokens_error::<InternallyTagged>( 756 &[ 757 Token::Seq { len: Some(2) }, 758 Token::Str("C"), 759 Token::Map { len: Some(0) }, 760 Token::MapEnd, 761 Token::SeqEnd, 762 ], 763 "invalid type: sequence, expected a map", 764 ); 765 766 assert_tokens( 767 &InternallyTagged::D(Newtype(BTreeMap::new())), 768 &[ 769 Token::Map { len: Some(1) }, 770 Token::Str("type"), 771 Token::Str("D"), 772 Token::MapEnd, 773 ], 774 ); 775 776 assert_tokens( 777 &InternallyTagged::E(Struct { f: 6 }), 778 &[ 779 Token::Struct { 780 name: "Struct", 781 len: 2, 782 }, 783 Token::Str("type"), 784 Token::Str("E"), 785 Token::Str("f"), 786 Token::U8(6), 787 Token::StructEnd, 788 ], 789 ); 790 791 assert_de_tokens( 792 &InternallyTagged::E(Struct { f: 6 }), 793 &[ 794 Token::Seq { len: Some(2) }, 795 Token::Str("E"), 796 Token::U8(6), 797 Token::SeqEnd, 798 ], 799 ); 800 801 assert_de_tokens_error::<InternallyTagged>( 802 &[Token::Map { len: Some(0) }, Token::MapEnd], 803 "missing field `type`", 804 ); 805 806 assert_de_tokens_error::<InternallyTagged>( 807 &[ 808 Token::Map { len: Some(1) }, 809 Token::Str("type"), 810 Token::Str("Z"), 811 Token::MapEnd, 812 ], 813 "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`", 814 ); 815} 816 817#[test] 818fn test_internally_tagged_enum_with_untagged_variant() { 819 #[derive(Debug, PartialEq, Serialize, Deserialize)] 820 #[serde(tag = "kind")] 821 enum InternallyTagged { 822 Tagged { 823 a: u8, 824 }, 825 #[serde(untagged)] 826 Untagged { 827 kind: String, 828 b: u8, 829 }, 830 } 831 832 assert_de_tokens( 833 &InternallyTagged::Tagged { a: 1 }, 834 &[ 835 Token::Map { len: Some(2) }, 836 Token::Str("kind"), 837 Token::Str("Tagged"), 838 Token::Str("a"), 839 Token::U8(1), 840 Token::MapEnd, 841 ], 842 ); 843 844 assert_tokens( 845 &InternallyTagged::Tagged { a: 1 }, 846 &[ 847 Token::Struct { 848 name: "InternallyTagged", 849 len: 2, 850 }, 851 Token::Str("kind"), 852 Token::Str("Tagged"), 853 Token::Str("a"), 854 Token::U8(1), 855 Token::StructEnd, 856 ], 857 ); 858 859 assert_de_tokens( 860 &InternallyTagged::Untagged { 861 kind: "Foo".to_owned(), 862 b: 2, 863 }, 864 &[ 865 Token::Map { len: Some(2) }, 866 Token::Str("kind"), 867 Token::Str("Foo"), 868 Token::Str("b"), 869 Token::U8(2), 870 Token::MapEnd, 871 ], 872 ); 873 874 assert_tokens( 875 &InternallyTagged::Untagged { 876 kind: "Foo".to_owned(), 877 b: 2, 878 }, 879 &[ 880 Token::Struct { 881 name: "InternallyTagged", 882 len: 2, 883 }, 884 Token::Str("kind"), 885 Token::Str("Foo"), 886 Token::Str("b"), 887 Token::U8(2), 888 Token::StructEnd, 889 ], 890 ); 891 892 assert_tokens( 893 &InternallyTagged::Untagged { 894 kind: "Tagged".to_owned(), 895 b: 2, 896 }, 897 &[ 898 Token::Struct { 899 name: "InternallyTagged", 900 len: 2, 901 }, 902 Token::Str("kind"), 903 Token::Str("Tagged"), 904 Token::Str("b"), 905 Token::U8(2), 906 Token::StructEnd, 907 ], 908 ); 909} 910 911#[test] 912fn test_internally_tagged_bytes() { 913 #[derive(Debug, PartialEq, Deserialize)] 914 #[serde(tag = "type")] 915 enum InternallyTagged { 916 String { 917 string: String, 918 }, 919 Bytes { 920 #[serde(with = "bytes")] 921 bytes: Vec<u8>, 922 }, 923 } 924 925 assert_de_tokens( 926 &InternallyTagged::String { 927 string: "\0".to_owned(), 928 }, 929 &[ 930 Token::Struct { 931 name: "String", 932 len: 2, 933 }, 934 Token::Str("type"), 935 Token::Str("String"), 936 Token::Str("string"), 937 Token::Str("\0"), 938 Token::StructEnd, 939 ], 940 ); 941 942 assert_de_tokens( 943 &InternallyTagged::String { 944 string: "\0".to_owned(), 945 }, 946 &[ 947 Token::Struct { 948 name: "String", 949 len: 2, 950 }, 951 Token::Str("type"), 952 Token::Str("String"), 953 Token::Str("string"), 954 Token::String("\0"), 955 Token::StructEnd, 956 ], 957 ); 958 959 assert_de_tokens( 960 &InternallyTagged::String { 961 string: "\0".to_owned(), 962 }, 963 &[ 964 Token::Struct { 965 name: "String", 966 len: 2, 967 }, 968 Token::Str("type"), 969 Token::Str("String"), 970 Token::Str("string"), 971 Token::Bytes(b"\0"), 972 Token::StructEnd, 973 ], 974 ); 975 976 assert_de_tokens( 977 &InternallyTagged::String { 978 string: "\0".to_owned(), 979 }, 980 &[ 981 Token::Struct { 982 name: "String", 983 len: 2, 984 }, 985 Token::Str("type"), 986 Token::Str("String"), 987 Token::Str("string"), 988 Token::ByteBuf(b"\0"), 989 Token::StructEnd, 990 ], 991 ); 992 993 assert_de_tokens( 994 &InternallyTagged::Bytes { bytes: vec![0] }, 995 &[ 996 Token::Struct { 997 name: "Bytes", 998 len: 2, 999 }, 1000 Token::Str("type"), 1001 Token::Str("Bytes"), 1002 Token::Str("bytes"), 1003 Token::Str("\0"), 1004 Token::StructEnd, 1005 ], 1006 ); 1007 1008 assert_de_tokens( 1009 &InternallyTagged::Bytes { bytes: vec![0] }, 1010 &[ 1011 Token::Struct { 1012 name: "Bytes", 1013 len: 2, 1014 }, 1015 Token::Str("type"), 1016 Token::Str("Bytes"), 1017 Token::Str("bytes"), 1018 Token::String("\0"), 1019 Token::StructEnd, 1020 ], 1021 ); 1022 1023 assert_de_tokens( 1024 &InternallyTagged::Bytes { bytes: vec![0] }, 1025 &[ 1026 Token::Struct { 1027 name: "Bytes", 1028 len: 2, 1029 }, 1030 Token::Str("type"), 1031 Token::Str("Bytes"), 1032 Token::Str("bytes"), 1033 Token::Bytes(b"\0"), 1034 Token::StructEnd, 1035 ], 1036 ); 1037 1038 assert_de_tokens( 1039 &InternallyTagged::Bytes { bytes: vec![0] }, 1040 &[ 1041 Token::Struct { 1042 name: "Bytes", 1043 len: 2, 1044 }, 1045 Token::Str("type"), 1046 Token::Str("Bytes"), 1047 Token::Str("bytes"), 1048 Token::ByteBuf(b"\0"), 1049 Token::StructEnd, 1050 ], 1051 ); 1052 1053 assert_de_tokens( 1054 &InternallyTagged::Bytes { bytes: vec![0] }, 1055 &[ 1056 Token::Struct { 1057 name: "Bytes", 1058 len: 2, 1059 }, 1060 Token::Str("type"), 1061 Token::Str("Bytes"), 1062 Token::Str("bytes"), 1063 Token::Seq { len: Some(1) }, 1064 Token::U8(0), 1065 Token::SeqEnd, 1066 Token::StructEnd, 1067 ], 1068 ); 1069} 1070 1071#[test] 1072fn test_internally_tagged_struct_variant_containing_unit_variant() { 1073 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1074 pub enum Level { 1075 Info, 1076 } 1077 1078 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1079 #[serde(tag = "action")] 1080 pub enum Message { 1081 Log { level: Level }, 1082 } 1083 1084 assert_de_tokens( 1085 &Message::Log { level: Level::Info }, 1086 &[ 1087 Token::Struct { 1088 name: "Message", 1089 len: 2, 1090 }, 1091 Token::Str("action"), 1092 Token::Str("Log"), 1093 Token::Str("level"), 1094 Token::BorrowedStr("Info"), 1095 Token::StructEnd, 1096 ], 1097 ); 1098 1099 assert_de_tokens( 1100 &Message::Log { level: Level::Info }, 1101 &[ 1102 Token::Map { len: Some(2) }, 1103 Token::Str("action"), 1104 Token::Str("Log"), 1105 Token::Str("level"), 1106 Token::BorrowedStr("Info"), 1107 Token::MapEnd, 1108 ], 1109 ); 1110 1111 assert_de_tokens( 1112 &Message::Log { level: Level::Info }, 1113 &[ 1114 Token::Seq { len: Some(2) }, 1115 Token::Str("Log"), 1116 Token::BorrowedStr("Info"), 1117 Token::SeqEnd, 1118 ], 1119 ); 1120} 1121 1122#[test] 1123fn test_internally_tagged_borrow() { 1124 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1125 #[serde(tag = "type")] 1126 pub enum Input<'a> { 1127 Package { name: &'a str }, 1128 } 1129 1130 assert_tokens( 1131 &Input::Package { name: "borrowed" }, 1132 &[ 1133 Token::Struct { 1134 name: "Input", 1135 len: 2, 1136 }, 1137 Token::BorrowedStr("type"), 1138 Token::BorrowedStr("Package"), 1139 Token::BorrowedStr("name"), 1140 Token::BorrowedStr("borrowed"), 1141 Token::StructEnd, 1142 ], 1143 ); 1144} 1145 1146#[test] 1147fn test_adjacently_tagged_enum() { 1148 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1149 #[serde(tag = "t", content = "c")] 1150 enum AdjacentlyTagged<T> { 1151 Unit, 1152 Newtype(T), 1153 Tuple(u8, u8), 1154 Struct { f: u8 }, 1155 } 1156 1157 // unit with no content 1158 assert_ser_tokens( 1159 &AdjacentlyTagged::Unit::<u8>, 1160 &[ 1161 Token::Struct { 1162 name: "AdjacentlyTagged", 1163 len: 1, 1164 }, 1165 Token::Str("t"), 1166 Token::UnitVariant { 1167 name: "AdjacentlyTagged", 1168 variant: "Unit", 1169 }, 1170 Token::StructEnd, 1171 ], 1172 ); 1173 1174 // unit with no content 1175 assert_de_tokens( 1176 &AdjacentlyTagged::Unit::<u8>, 1177 &[ 1178 Token::Struct { 1179 name: "AdjacentlyTagged", 1180 len: 2, 1181 }, 1182 Token::Str("t"), 1183 Token::UnitVariant { 1184 name: "AdjacentlyTagged", 1185 variant: "Unit", 1186 }, 1187 Token::StructEnd, 1188 ], 1189 ); 1190 1191 // unit with tag first 1192 assert_de_tokens( 1193 &AdjacentlyTagged::Unit::<u8>, 1194 &[ 1195 Token::Struct { 1196 name: "AdjacentlyTagged", 1197 len: 2, 1198 }, 1199 Token::Str("t"), 1200 Token::UnitVariant { 1201 name: "AdjacentlyTagged", 1202 variant: "Unit", 1203 }, 1204 Token::Str("c"), 1205 Token::Unit, 1206 Token::StructEnd, 1207 ], 1208 ); 1209 1210 // unit with content first 1211 assert_de_tokens( 1212 &AdjacentlyTagged::Unit::<u8>, 1213 &[ 1214 Token::Struct { 1215 name: "AdjacentlyTagged", 1216 len: 2, 1217 }, 1218 Token::Str("c"), 1219 Token::Unit, 1220 Token::Str("t"), 1221 Token::UnitVariant { 1222 name: "AdjacentlyTagged", 1223 variant: "Unit", 1224 }, 1225 Token::StructEnd, 1226 ], 1227 ); 1228 1229 // unit with excess content (f, g, h) 1230 assert_de_tokens( 1231 &AdjacentlyTagged::Unit::<u8>, 1232 &[ 1233 Token::Struct { 1234 name: "AdjacentlyTagged", 1235 len: 2, 1236 }, 1237 Token::Str("f"), 1238 Token::Unit, 1239 Token::Str("t"), 1240 Token::UnitVariant { 1241 name: "AdjacentlyTagged", 1242 variant: "Unit", 1243 }, 1244 Token::Str("g"), 1245 Token::Unit, 1246 Token::Str("c"), 1247 Token::Unit, 1248 Token::Str("h"), 1249 Token::Unit, 1250 Token::StructEnd, 1251 ], 1252 ); 1253 1254 // newtype with tag first 1255 assert_tokens( 1256 &AdjacentlyTagged::Newtype::<u8>(1), 1257 &[ 1258 Token::Struct { 1259 name: "AdjacentlyTagged", 1260 len: 2, 1261 }, 1262 Token::Str("t"), 1263 Token::UnitVariant { 1264 name: "AdjacentlyTagged", 1265 variant: "Newtype", 1266 }, 1267 Token::Str("c"), 1268 Token::U8(1), 1269 Token::StructEnd, 1270 ], 1271 ); 1272 1273 // newtype with content first 1274 assert_de_tokens( 1275 &AdjacentlyTagged::Newtype::<u8>(1), 1276 &[ 1277 Token::Struct { 1278 name: "AdjacentlyTagged", 1279 len: 2, 1280 }, 1281 Token::Str("c"), 1282 Token::U8(1), 1283 Token::Str("t"), 1284 Token::UnitVariant { 1285 name: "AdjacentlyTagged", 1286 variant: "Newtype", 1287 }, 1288 Token::StructEnd, 1289 ], 1290 ); 1291 1292 // optional newtype with no content field 1293 assert_de_tokens( 1294 &AdjacentlyTagged::Newtype::<Option<u8>>(None), 1295 &[ 1296 Token::Struct { 1297 name: "AdjacentlyTagged", 1298 len: 1, 1299 }, 1300 Token::Str("t"), 1301 Token::UnitVariant { 1302 name: "AdjacentlyTagged", 1303 variant: "Newtype", 1304 }, 1305 Token::StructEnd, 1306 ], 1307 ); 1308 1309 // tuple with tag first 1310 assert_tokens( 1311 &AdjacentlyTagged::Tuple::<u8>(1, 1), 1312 &[ 1313 Token::Struct { 1314 name: "AdjacentlyTagged", 1315 len: 2, 1316 }, 1317 Token::Str("t"), 1318 Token::UnitVariant { 1319 name: "AdjacentlyTagged", 1320 variant: "Tuple", 1321 }, 1322 Token::Str("c"), 1323 Token::Tuple { len: 2 }, 1324 Token::U8(1), 1325 Token::U8(1), 1326 Token::TupleEnd, 1327 Token::StructEnd, 1328 ], 1329 ); 1330 1331 // tuple with content first 1332 assert_de_tokens( 1333 &AdjacentlyTagged::Tuple::<u8>(1, 1), 1334 &[ 1335 Token::Struct { 1336 name: "AdjacentlyTagged", 1337 len: 2, 1338 }, 1339 Token::Str("c"), 1340 Token::Tuple { len: 2 }, 1341 Token::U8(1), 1342 Token::U8(1), 1343 Token::TupleEnd, 1344 Token::Str("t"), 1345 Token::UnitVariant { 1346 name: "AdjacentlyTagged", 1347 variant: "Tuple", 1348 }, 1349 Token::StructEnd, 1350 ], 1351 ); 1352 1353 // struct with tag first 1354 assert_tokens( 1355 &AdjacentlyTagged::Struct::<u8> { f: 1 }, 1356 &[ 1357 Token::Struct { 1358 name: "AdjacentlyTagged", 1359 len: 2, 1360 }, 1361 Token::Str("t"), 1362 Token::UnitVariant { 1363 name: "AdjacentlyTagged", 1364 variant: "Struct", 1365 }, 1366 Token::Str("c"), 1367 Token::Struct { 1368 name: "Struct", 1369 len: 1, 1370 }, 1371 Token::Str("f"), 1372 Token::U8(1), 1373 Token::StructEnd, 1374 Token::StructEnd, 1375 ], 1376 ); 1377 1378 // struct with content first 1379 assert_de_tokens( 1380 &AdjacentlyTagged::Struct::<u8> { f: 1 }, 1381 &[ 1382 Token::Struct { 1383 name: "AdjacentlyTagged", 1384 len: 2, 1385 }, 1386 Token::Str("c"), 1387 Token::Struct { 1388 name: "Struct", 1389 len: 1, 1390 }, 1391 Token::Str("f"), 1392 Token::U8(1), 1393 Token::StructEnd, 1394 Token::Str("t"), 1395 Token::UnitVariant { 1396 name: "AdjacentlyTagged", 1397 variant: "Struct", 1398 }, 1399 Token::StructEnd, 1400 ], 1401 ); 1402 1403 // integer field keys 1404 assert_de_tokens( 1405 &AdjacentlyTagged::Newtype::<u8>(1), 1406 &[ 1407 Token::Struct { 1408 name: "AdjacentlyTagged", 1409 len: 2, 1410 }, 1411 Token::U64(1), // content field 1412 Token::U8(1), 1413 Token::U64(0), // tag field 1414 Token::UnitVariant { 1415 name: "AdjacentlyTagged", 1416 variant: "Newtype", 1417 }, 1418 Token::StructEnd, 1419 ], 1420 ); 1421 1422 // byte-array field keys 1423 assert_de_tokens( 1424 &AdjacentlyTagged::Newtype::<u8>(1), 1425 &[ 1426 Token::Struct { 1427 name: "AdjacentlyTagged", 1428 len: 2, 1429 }, 1430 Token::Bytes(b"c"), 1431 Token::U8(1), 1432 Token::Bytes(b"t"), 1433 Token::UnitVariant { 1434 name: "AdjacentlyTagged", 1435 variant: "Newtype", 1436 }, 1437 Token::StructEnd, 1438 ], 1439 ); 1440} 1441 1442#[test] 1443fn test_adjacently_tagged_enum_deny_unknown_fields() { 1444 #[derive(Debug, PartialEq, Deserialize)] 1445 #[serde(tag = "t", content = "c", deny_unknown_fields)] 1446 enum AdjacentlyTagged { 1447 Unit, 1448 } 1449 1450 assert_de_tokens( 1451 &AdjacentlyTagged::Unit, 1452 &[ 1453 Token::Struct { 1454 name: "AdjacentlyTagged", 1455 len: 2, 1456 }, 1457 Token::Str("t"), 1458 Token::UnitVariant { 1459 name: "AdjacentlyTagged", 1460 variant: "Unit", 1461 }, 1462 Token::Str("c"), 1463 Token::Unit, 1464 Token::StructEnd, 1465 ], 1466 ); 1467 1468 assert_de_tokens_error::<AdjacentlyTagged>( 1469 &[ 1470 Token::Struct { 1471 name: "AdjacentlyTagged", 1472 len: 2, 1473 }, 1474 Token::Str("t"), 1475 Token::UnitVariant { 1476 name: "AdjacentlyTagged", 1477 variant: "Unit", 1478 }, 1479 Token::Str("c"), 1480 Token::Unit, 1481 Token::Str("h"), 1482 ], 1483 r#"invalid value: string "h", expected "t" or "c""#, 1484 ); 1485 1486 assert_de_tokens_error::<AdjacentlyTagged>( 1487 &[ 1488 Token::Struct { 1489 name: "AdjacentlyTagged", 1490 len: 2, 1491 }, 1492 Token::Str("h"), 1493 ], 1494 r#"invalid value: string "h", expected "t" or "c""#, 1495 ); 1496 1497 assert_de_tokens_error::<AdjacentlyTagged>( 1498 &[ 1499 Token::Struct { 1500 name: "AdjacentlyTagged", 1501 len: 2, 1502 }, 1503 Token::Str("c"), 1504 Token::Unit, 1505 Token::Str("h"), 1506 ], 1507 r#"invalid value: string "h", expected "t" or "c""#, 1508 ); 1509 1510 assert_de_tokens_error::<AdjacentlyTagged>( 1511 &[ 1512 Token::Struct { 1513 name: "AdjacentlyTagged", 1514 len: 2, 1515 }, 1516 Token::U64(0), // tag field 1517 Token::UnitVariant { 1518 name: "AdjacentlyTagged", 1519 variant: "Unit", 1520 }, 1521 Token::U64(3), 1522 ], 1523 r#"invalid value: integer `3`, expected "t" or "c""#, 1524 ); 1525 1526 assert_de_tokens_error::<AdjacentlyTagged>( 1527 &[ 1528 Token::Struct { 1529 name: "AdjacentlyTagged", 1530 len: 2, 1531 }, 1532 Token::Bytes(b"c"), 1533 Token::Unit, 1534 Token::Bytes(b"h"), 1535 ], 1536 r#"invalid value: byte array, expected "t" or "c""#, 1537 ); 1538} 1539 1540#[test] 1541fn test_enum_in_internally_tagged_enum() { 1542 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1543 #[serde(tag = "type")] 1544 enum Outer { 1545 Inner(Inner), 1546 } 1547 1548 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1549 enum Inner { 1550 Unit, 1551 Newtype(u8), 1552 Tuple(u8, u8), 1553 Struct { f: u8 }, 1554 } 1555 1556 assert_tokens( 1557 &Outer::Inner(Inner::Unit), 1558 &[ 1559 Token::Map { len: Some(2) }, 1560 Token::Str("type"), 1561 Token::Str("Inner"), 1562 Token::Str("Unit"), 1563 Token::Unit, 1564 Token::MapEnd, 1565 ], 1566 ); 1567 1568 assert_tokens( 1569 &Outer::Inner(Inner::Newtype(1)), 1570 &[ 1571 Token::Map { len: Some(2) }, 1572 Token::Str("type"), 1573 Token::Str("Inner"), 1574 Token::Str("Newtype"), 1575 Token::U8(1), 1576 Token::MapEnd, 1577 ], 1578 ); 1579 1580 // Reaches crate::private::de::content::VariantDeserializer::tuple_variant 1581 // Content::Seq case 1582 // via ContentDeserializer::deserialize_enum 1583 assert_tokens( 1584 &Outer::Inner(Inner::Tuple(1, 1)), 1585 &[ 1586 Token::Map { len: Some(2) }, 1587 Token::Str("type"), 1588 Token::Str("Inner"), 1589 Token::Str("Tuple"), 1590 Token::TupleStruct { 1591 name: "Tuple", 1592 len: 2, 1593 }, 1594 Token::U8(1), 1595 Token::U8(1), 1596 Token::TupleStructEnd, 1597 Token::MapEnd, 1598 ], 1599 ); 1600 1601 // Reaches crate::private::de::content::VariantDeserializer::struct_variant 1602 // Content::Map case 1603 // via ContentDeserializer::deserialize_enum 1604 assert_tokens( 1605 &Outer::Inner(Inner::Struct { f: 1 }), 1606 &[ 1607 Token::Map { len: Some(2) }, 1608 Token::Str("type"), 1609 Token::Str("Inner"), 1610 Token::Str("Struct"), 1611 Token::Struct { 1612 name: "Struct", 1613 len: 1, 1614 }, 1615 Token::Str("f"), 1616 Token::U8(1), 1617 Token::StructEnd, 1618 Token::MapEnd, 1619 ], 1620 ); 1621 1622 // Reaches crate::private::de::content::VariantDeserializer::struct_variant 1623 // Content::Seq case 1624 // via ContentDeserializer::deserialize_enum 1625 assert_de_tokens( 1626 &Outer::Inner(Inner::Struct { f: 1 }), 1627 &[ 1628 Token::Map { len: Some(2) }, 1629 Token::Str("type"), 1630 Token::Str("Inner"), 1631 Token::Str("Struct"), 1632 Token::Seq { len: Some(1) }, 1633 Token::U8(1), // f 1634 Token::SeqEnd, 1635 Token::MapEnd, 1636 ], 1637 ); 1638} 1639 1640#[test] 1641fn test_internally_tagged_struct() { 1642 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1643 #[serde(tag = "type")] 1644 pub struct Struct { 1645 a: u8, 1646 } 1647 1648 assert_tokens( 1649 &Struct { a: 1 }, 1650 &[ 1651 Token::Struct { 1652 name: "Struct", 1653 len: 2, 1654 }, 1655 Token::Str("type"), 1656 Token::Str("Struct"), 1657 Token::Str("a"), 1658 Token::U8(1), 1659 Token::StructEnd, 1660 ], 1661 ); 1662 1663 assert_de_tokens( 1664 &Struct { a: 1 }, 1665 &[ 1666 Token::Struct { 1667 name: "Struct", 1668 len: 1, 1669 }, 1670 Token::Str("a"), 1671 Token::U8(1), 1672 Token::StructEnd, 1673 ], 1674 ); 1675} 1676 1677#[test] 1678fn test_internally_tagged_braced_struct_with_zero_fields() { 1679 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1680 #[serde(tag = "type")] 1681 struct S {} 1682 1683 assert_tokens( 1684 &S {}, 1685 &[ 1686 Token::Struct { name: "S", len: 1 }, 1687 Token::Str("type"), 1688 Token::Str("S"), 1689 Token::StructEnd, 1690 ], 1691 ); 1692} 1693 1694#[test] 1695fn test_internally_tagged_struct_with_flattened_field() { 1696 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1697 #[serde(tag = "tag_struct")] 1698 pub struct Struct { 1699 #[serde(flatten)] 1700 pub flat: Enum, 1701 } 1702 1703 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1704 #[serde(tag = "tag_enum", content = "content")] 1705 pub enum Enum { 1706 A(u64), 1707 } 1708 1709 assert_tokens( 1710 &Struct { flat: Enum::A(0) }, 1711 &[ 1712 Token::Map { len: None }, 1713 Token::Str("tag_struct"), 1714 Token::Str("Struct"), 1715 Token::Str("tag_enum"), 1716 Token::UnitVariant { 1717 name: "Enum", 1718 variant: "A", 1719 }, 1720 Token::Str("content"), 1721 Token::U64(0), 1722 Token::MapEnd, 1723 ], 1724 ); 1725 1726 assert_de_tokens( 1727 &Struct { flat: Enum::A(0) }, 1728 &[ 1729 Token::Map { len: None }, 1730 Token::Str("tag_enum"), 1731 Token::Str("A"), 1732 Token::Str("content"), 1733 Token::U64(0), 1734 Token::MapEnd, 1735 ], 1736 ); 1737} 1738 1739#[test] 1740fn test_untagged_enum_with_flattened_integer_key() { 1741 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1742 #[serde(untagged)] 1743 pub enum Untagged { 1744 Variant { 1745 #[serde(flatten)] 1746 map: BTreeMap<u64, String>, 1747 }, 1748 } 1749 1750 assert_tokens( 1751 &Untagged::Variant { 1752 map: { 1753 let mut map = BTreeMap::new(); 1754 map.insert(100, "BTreeMap".to_owned()); 1755 map 1756 }, 1757 }, 1758 &[ 1759 Token::Map { len: None }, 1760 Token::U64(100), 1761 Token::Str("BTreeMap"), 1762 Token::MapEnd, 1763 ], 1764 ); 1765} 1766 1767#[test] 1768fn test_enum_in_untagged_enum() { 1769 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1770 #[serde(untagged)] 1771 enum Outer { 1772 Inner(Inner), 1773 } 1774 1775 #[derive(Debug, PartialEq, Serialize, Deserialize)] 1776 enum Inner { 1777 Unit, 1778 Newtype(u8), 1779 Tuple(u8, u8), 1780 Struct { f: u8 }, 1781 } 1782 1783 assert_tokens( 1784 &Outer::Inner(Inner::Unit), 1785 &[Token::UnitVariant { 1786 name: "Inner", 1787 variant: "Unit", 1788 }], 1789 ); 1790 1791 assert_tokens( 1792 &Outer::Inner(Inner::Newtype(1)), 1793 &[ 1794 Token::NewtypeVariant { 1795 name: "Inner", 1796 variant: "Newtype", 1797 }, 1798 Token::U8(1), 1799 ], 1800 ); 1801 1802 assert_tokens( 1803 &Outer::Inner(Inner::Tuple(1, 1)), 1804 &[ 1805 Token::TupleVariant { 1806 name: "Inner", 1807 variant: "Tuple", 1808 len: 2, 1809 }, 1810 Token::U8(1), 1811 Token::U8(1), 1812 Token::TupleVariantEnd, 1813 ], 1814 ); 1815 1816 assert_tokens( 1817 &Outer::Inner(Inner::Struct { f: 1 }), 1818 &[ 1819 Token::StructVariant { 1820 name: "Inner", 1821 variant: "Struct", 1822 len: 1, 1823 }, 1824 Token::Str("f"), 1825 Token::U8(1), 1826 Token::StructVariantEnd, 1827 ], 1828 ); 1829} 1830 1831#[test] 1832fn test_untagged_bytes() { 1833 #[derive(Debug, PartialEq, Deserialize)] 1834 #[serde(untagged)] 1835 enum Untagged { 1836 String { 1837 string: String, 1838 }, 1839 Bytes { 1840 #[serde(with = "bytes")] 1841 bytes: Vec<u8>, 1842 }, 1843 } 1844 1845 assert_de_tokens( 1846 &Untagged::String { 1847 string: "\0".to_owned(), 1848 }, 1849 &[ 1850 Token::Struct { 1851 name: "Untagged", 1852 len: 1, 1853 }, 1854 Token::Str("string"), 1855 Token::Str("\0"), 1856 Token::StructEnd, 1857 ], 1858 ); 1859 1860 assert_de_tokens( 1861 &Untagged::String { 1862 string: "\0".to_owned(), 1863 }, 1864 &[ 1865 Token::Struct { 1866 name: "Untagged", 1867 len: 1, 1868 }, 1869 Token::Str("string"), 1870 Token::String("\0"), 1871 Token::StructEnd, 1872 ], 1873 ); 1874 1875 assert_de_tokens( 1876 &Untagged::String { 1877 string: "\0".to_owned(), 1878 }, 1879 &[ 1880 Token::Struct { 1881 name: "Untagged", 1882 len: 1, 1883 }, 1884 Token::Str("string"), 1885 Token::Bytes(b"\0"), 1886 Token::StructEnd, 1887 ], 1888 ); 1889 1890 assert_de_tokens( 1891 &Untagged::String { 1892 string: "\0".to_owned(), 1893 }, 1894 &[ 1895 Token::Struct { 1896 name: "Untagged", 1897 len: 1, 1898 }, 1899 Token::Str("string"), 1900 Token::ByteBuf(b"\0"), 1901 Token::StructEnd, 1902 ], 1903 ); 1904 1905 assert_de_tokens( 1906 &Untagged::Bytes { bytes: vec![0] }, 1907 &[ 1908 Token::Struct { 1909 name: "Untagged", 1910 len: 1, 1911 }, 1912 Token::Str("bytes"), 1913 Token::Str("\0"), 1914 Token::StructEnd, 1915 ], 1916 ); 1917 1918 assert_de_tokens( 1919 &Untagged::Bytes { bytes: vec![0] }, 1920 &[ 1921 Token::Struct { 1922 name: "Untagged", 1923 len: 1, 1924 }, 1925 Token::Str("bytes"), 1926 Token::String("\0"), 1927 Token::StructEnd, 1928 ], 1929 ); 1930 1931 assert_de_tokens( 1932 &Untagged::Bytes { bytes: vec![0] }, 1933 &[ 1934 Token::Struct { 1935 name: "Untagged", 1936 len: 1, 1937 }, 1938 Token::Str("bytes"), 1939 Token::Bytes(b"\0"), 1940 Token::StructEnd, 1941 ], 1942 ); 1943 1944 assert_de_tokens( 1945 &Untagged::Bytes { bytes: vec![0] }, 1946 &[ 1947 Token::Struct { 1948 name: "Untagged", 1949 len: 1, 1950 }, 1951 Token::Str("bytes"), 1952 Token::ByteBuf(b"\0"), 1953 Token::StructEnd, 1954 ], 1955 ); 1956 1957 assert_de_tokens( 1958 &Untagged::Bytes { bytes: vec![0] }, 1959 &[ 1960 Token::Struct { 1961 name: "Untagged", 1962 len: 1, 1963 }, 1964 Token::Str("bytes"), 1965 Token::Seq { len: Some(1) }, 1966 Token::U8(0), 1967 Token::SeqEnd, 1968 Token::StructEnd, 1969 ], 1970 ); 1971} 1972 1973#[test] 1974fn test_rename_all() { 1975 #[derive(Serialize, Deserialize, Debug, PartialEq)] 1976 #[serde(rename_all = "snake_case")] 1977 enum E { 1978 #[serde(rename_all = "camelCase")] 1979 Serialize { 1980 serialize: bool, 1981 serialize_seq: bool, 1982 }, 1983 #[serde(rename_all = "kebab-case")] 1984 SerializeSeq { 1985 serialize: bool, 1986 serialize_seq: bool, 1987 }, 1988 #[serde(rename_all = "SCREAMING_SNAKE_CASE")] 1989 SerializeMap { 1990 serialize: bool, 1991 serialize_seq: bool, 1992 }, 1993 } 1994 1995 #[derive(Serialize, Deserialize, Debug, PartialEq)] 1996 #[serde(rename_all = "PascalCase")] 1997 struct S { 1998 serialize: bool, 1999 serialize_seq: bool, 2000 } 2001 2002 #[derive(Serialize, Deserialize, Debug, PartialEq)] 2003 #[serde(rename_all = "SCREAMING-KEBAB-CASE")] 2004 struct ScreamingKebab { 2005 serialize: bool, 2006 serialize_seq: bool, 2007 } 2008 2009 assert_tokens( 2010 &E::Serialize { 2011 serialize: true, 2012 serialize_seq: true, 2013 }, 2014 &[ 2015 Token::StructVariant { 2016 name: "E", 2017 variant: "serialize", 2018 len: 2, 2019 }, 2020 Token::Str("serialize"), 2021 Token::Bool(true), 2022 Token::Str("serializeSeq"), 2023 Token::Bool(true), 2024 Token::StructVariantEnd, 2025 ], 2026 ); 2027 2028 assert_tokens( 2029 &E::SerializeSeq { 2030 serialize: true, 2031 serialize_seq: true, 2032 }, 2033 &[ 2034 Token::StructVariant { 2035 name: "E", 2036 variant: "serialize_seq", 2037 len: 2, 2038 }, 2039 Token::Str("serialize"), 2040 Token::Bool(true), 2041 Token::Str("serialize-seq"), 2042 Token::Bool(true), 2043 Token::StructVariantEnd, 2044 ], 2045 ); 2046 2047 assert_tokens( 2048 &E::SerializeMap { 2049 serialize: true, 2050 serialize_seq: true, 2051 }, 2052 &[ 2053 Token::StructVariant { 2054 name: "E", 2055 variant: "serialize_map", 2056 len: 2, 2057 }, 2058 Token::Str("SERIALIZE"), 2059 Token::Bool(true), 2060 Token::Str("SERIALIZE_SEQ"), 2061 Token::Bool(true), 2062 Token::StructVariantEnd, 2063 ], 2064 ); 2065 2066 assert_tokens( 2067 &S { 2068 serialize: true, 2069 serialize_seq: true, 2070 }, 2071 &[ 2072 Token::Struct { name: "S", len: 2 }, 2073 Token::Str("Serialize"), 2074 Token::Bool(true), 2075 Token::Str("SerializeSeq"), 2076 Token::Bool(true), 2077 Token::StructEnd, 2078 ], 2079 ); 2080 2081 assert_tokens( 2082 &ScreamingKebab { 2083 serialize: true, 2084 serialize_seq: true, 2085 }, 2086 &[ 2087 Token::Struct { 2088 name: "ScreamingKebab", 2089 len: 2, 2090 }, 2091 Token::Str("SERIALIZE"), 2092 Token::Bool(true), 2093 Token::Str("SERIALIZE-SEQ"), 2094 Token::Bool(true), 2095 Token::StructEnd, 2096 ], 2097 ); 2098} 2099 2100#[test] 2101fn test_rename_all_fields() { 2102 #[derive(Serialize, Deserialize, Debug, PartialEq)] 2103 #[serde(rename_all_fields = "kebab-case")] 2104 enum E { 2105 V1, 2106 V2(bool), 2107 V3 { 2108 a_field: bool, 2109 another_field: bool, 2110 #[serde(rename = "last-field")] 2111 yet_another_field: bool, 2112 }, 2113 #[serde(rename_all = "snake_case")] 2114 V4 { 2115 a_field: bool, 2116 }, 2117 } 2118 2119 assert_tokens( 2120 &E::V3 { 2121 a_field: true, 2122 another_field: true, 2123 yet_another_field: true, 2124 }, 2125 &[ 2126 Token::StructVariant { 2127 name: "E", 2128 variant: "V3", 2129 len: 3, 2130 }, 2131 Token::Str("a-field"), 2132 Token::Bool(true), 2133 Token::Str("another-field"), 2134 Token::Bool(true), 2135 Token::Str("last-field"), 2136 Token::Bool(true), 2137 Token::StructVariantEnd, 2138 ], 2139 ); 2140 2141 assert_tokens( 2142 &E::V4 { a_field: true }, 2143 &[ 2144 Token::StructVariant { 2145 name: "E", 2146 variant: "V4", 2147 len: 1, 2148 }, 2149 Token::Str("a_field"), 2150 Token::Bool(true), 2151 Token::StructVariantEnd, 2152 ], 2153 ); 2154} 2155 2156#[test] 2157fn test_untagged_newtype_variant_containing_unit_struct_not_map() { 2158 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2159 struct Unit; 2160 2161 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2162 #[serde(untagged)] 2163 enum Message { 2164 Unit(Unit), 2165 Map(BTreeMap<String, String>), 2166 } 2167 2168 assert_tokens( 2169 &Message::Map(BTreeMap::new()), 2170 &[Token::Map { len: Some(0) }, Token::MapEnd], 2171 ); 2172} 2173 2174#[test] 2175fn test_internally_tagged_newtype_variant_containing_unit_struct() { 2176 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2177 struct Info; 2178 2179 #[derive(Debug, PartialEq, Serialize, Deserialize)] 2180 #[serde(tag = "topic")] 2181 enum Message { 2182 Info(Info), 2183 } 2184 2185 assert_tokens( 2186 &Message::Info(Info), 2187 &[ 2188 Token::Map { len: Some(1) }, 2189 Token::Str("topic"), 2190 Token::Str("Info"), 2191 Token::MapEnd, 2192 ], 2193 ); 2194 2195 assert_de_tokens( 2196 &Message::Info(Info), 2197 &[ 2198 Token::Struct { 2199 name: "Message", 2200 len: 1, 2201 }, 2202 Token::Str("topic"), 2203 Token::Str("Info"), 2204 Token::StructEnd, 2205 ], 2206 ); 2207 2208 assert_de_tokens( 2209 &Message::Info(Info), 2210 &[ 2211 Token::Seq { len: Some(1) }, 2212 Token::Str("Info"), 2213 Token::SeqEnd, 2214 ], 2215 ); 2216} 2217 2218#[test] 2219fn test_packed_struct_can_derive_serialize() { 2220 #[derive(Copy, Clone, Serialize)] 2221 #[repr(packed, C)] 2222 struct PackedC { 2223 t: f32, 2224 } 2225 2226 #[derive(Copy, Clone, Serialize)] 2227 #[repr(C, packed)] 2228 struct CPacked { 2229 t: f32, 2230 } 2231 2232 #[derive(Copy, Clone, Serialize)] 2233 #[repr(C, packed(2))] 2234 struct CPacked2 { 2235 t: f32, 2236 } 2237 2238 #[derive(Copy, Clone, Serialize)] 2239 #[repr(packed(2), C)] 2240 struct Packed2C { 2241 t: f32, 2242 } 2243} 2244