1 #![deny(trivial_numeric_casts)]
2 #![allow(
3 clippy::enum_variant_names,
4 clippy::redundant_field_names,
5 clippy::too_many_lines
6 )]
7
8 mod bytes;
9
10 use serde::{Deserialize, Serialize};
11 use serde_test::{
12 assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token,
13 };
14
15 use std::collections::BTreeMap;
16 use 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)]
23 enum Void {}
24
25 #[derive(Debug, PartialEq, Serialize, Deserialize)]
26 struct NamedUnit;
27
28 #[derive(Debug, PartialEq, Serialize)]
29 struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
30
31 #[derive(Debug, PartialEq, Deserialize)]
32 struct DeNamedTuple<A, B, C>(A, B, C);
33
34 #[derive(Debug, PartialEq, Serialize)]
35 struct 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)]
42 struct DeNamedMap<A, B, C> {
43 a: A,
44 b: B,
45 c: C,
46 }
47
48 #[derive(Debug, PartialEq, Serialize)]
49 enum SerEnum<'a, B: 'a, C: 'a, D>
50 where
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)]
64 enum 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)]
76 enum 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)]
84 pub struct GenericStruct<T> {
85 x: T,
86 }
87
88 #[derive(Debug, PartialEq, Serialize, Deserialize)]
89 pub struct GenericNewTypeStruct<T>(T);
90
91 #[derive(Debug, PartialEq, Serialize, Deserialize)]
92 pub struct GenericTupleStruct<T, U>(T, U);
93
94 #[derive(Debug, PartialEq, Serialize, Deserialize)]
95 pub enum GenericEnum<T, U> {
96 Unit,
97 NewType(T),
98 Seq(T, U),
99 Map { x: T, y: U },
100 }
101
102 trait AssociatedType {
103 type X;
104 }
105
106 impl AssociatedType for i32 {
107 type X = i32;
108 }
109
110 #[derive(Debug, PartialEq, Serialize, Deserialize)]
111 struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
112 phantom: PhantomData<T>,
113 }
114
115 #[test]
test_named_unit()116 fn test_named_unit() {
117 assert_tokens(&NamedUnit, &[Token::UnitStruct { name: "NamedUnit" }]);
118 }
119
120 #[test]
test_ser_named_tuple()121 fn 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]
test_de_named_tuple()141 fn 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]
test_ser_named_map()169 fn 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]
test_de_named_map()197 fn 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]
test_ser_enum_unit()217 fn 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]
test_ser_enum_seq()228 fn 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]
test_ser_enum_map()252 fn 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]
test_de_enum_unit()285 fn 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]
test_de_enum_seq()296 fn 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]
test_de_enum_map()320 fn 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]
test_lifetimes()353 fn 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]
test_generic_struct()408 fn 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]
test_generic_newtype_struct()424 fn 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]
test_untagged_newtype_struct()437 fn 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]
test_adjacently_tagged_newtype_struct()457 fn 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::Str("Newtype"),
476 Token::StructEnd,
477 ],
478 );
479 }
480
481 #[test]
test_generic_tuple_struct()482 fn test_generic_tuple_struct() {
483 assert_tokens(
484 &GenericTupleStruct(5u32, 6u32),
485 &[
486 Token::TupleStruct {
487 name: "GenericTupleStruct",
488 len: 2,
489 },
490 Token::U32(5),
491 Token::U32(6),
492 Token::TupleStructEnd,
493 ],
494 );
495 }
496
497 #[test]
test_generic_enum_unit()498 fn test_generic_enum_unit() {
499 assert_tokens(
500 &GenericEnum::Unit::<u32, u32>,
501 &[Token::UnitVariant {
502 name: "GenericEnum",
503 variant: "Unit",
504 }],
505 );
506 }
507
508 #[test]
test_generic_enum_newtype()509 fn test_generic_enum_newtype() {
510 assert_tokens(
511 &GenericEnum::NewType::<u32, u32>(5),
512 &[
513 Token::NewtypeVariant {
514 name: "GenericEnum",
515 variant: "NewType",
516 },
517 Token::U32(5),
518 ],
519 );
520 }
521
522 #[test]
test_generic_enum_seq()523 fn test_generic_enum_seq() {
524 assert_tokens(
525 &GenericEnum::Seq::<u32, u32>(5, 6),
526 &[
527 Token::TupleVariant {
528 name: "GenericEnum",
529 variant: "Seq",
530 len: 2,
531 },
532 Token::U32(5),
533 Token::U32(6),
534 Token::TupleVariantEnd,
535 ],
536 );
537 }
538
539 #[test]
test_generic_enum_map()540 fn test_generic_enum_map() {
541 assert_tokens(
542 &GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
543 &[
544 Token::StructVariant {
545 name: "GenericEnum",
546 variant: "Map",
547 len: 2,
548 },
549 Token::Str("x"),
550 Token::U32(5),
551 Token::Str("y"),
552 Token::U32(6),
553 Token::StructVariantEnd,
554 ],
555 );
556 }
557
558 #[test]
test_default_ty_param()559 fn test_default_ty_param() {
560 assert_tokens(
561 &DefaultTyParam::<i32> {
562 phantom: PhantomData,
563 },
564 &[
565 Token::Struct {
566 name: "DefaultTyParam",
567 len: 1,
568 },
569 Token::Str("phantom"),
570 Token::UnitStruct {
571 name: "PhantomData",
572 },
573 Token::StructEnd,
574 ],
575 );
576 }
577
578 #[test]
test_enum_state_field()579 fn test_enum_state_field() {
580 #[derive(Debug, PartialEq, Serialize, Deserialize)]
581 enum SomeEnum {
582 Key { key: char, state: bool },
583 }
584
585 assert_tokens(
586 &SomeEnum::Key {
587 key: 'a',
588 state: true,
589 },
590 &[
591 Token::StructVariant {
592 name: "SomeEnum",
593 variant: "Key",
594 len: 2,
595 },
596 Token::Str("key"),
597 Token::Char('a'),
598 Token::Str("state"),
599 Token::Bool(true),
600 Token::StructVariantEnd,
601 ],
602 );
603 }
604
605 #[test]
test_untagged_enum()606 fn test_untagged_enum() {
607 #[derive(Debug, PartialEq, Serialize, Deserialize)]
608 #[serde(untagged)]
609 enum Untagged {
610 A { a: u8 },
611 B { b: u8 },
612 C,
613 D(u8),
614 E(String),
615 F(u8, u8),
616 }
617
618 assert_tokens(
619 &Untagged::A { a: 1 },
620 &[
621 Token::Struct {
622 name: "Untagged",
623 len: 1,
624 },
625 Token::Str("a"),
626 Token::U8(1),
627 Token::StructEnd,
628 ],
629 );
630
631 assert_tokens(
632 &Untagged::B { b: 2 },
633 &[
634 Token::Struct {
635 name: "Untagged",
636 len: 1,
637 },
638 Token::Str("b"),
639 Token::U8(2),
640 Token::StructEnd,
641 ],
642 );
643
644 // Serializes to unit, deserializes from either depending on format's
645 // preference.
646 assert_tokens(&Untagged::C, &[Token::Unit]);
647 assert_de_tokens(&Untagged::C, &[Token::None]);
648
649 assert_tokens(&Untagged::D(4), &[Token::U8(4)]);
650 assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]);
651
652 assert_tokens(
653 &Untagged::F(1, 2),
654 &[
655 Token::Tuple { len: 2 },
656 Token::U8(1),
657 Token::U8(2),
658 Token::TupleEnd,
659 ],
660 );
661
662 assert_de_tokens_error::<Untagged>(
663 &[Token::Tuple { len: 1 }, Token::U8(1), Token::TupleEnd],
664 "data did not match any variant of untagged enum Untagged",
665 );
666
667 assert_de_tokens_error::<Untagged>(
668 &[
669 Token::Tuple { len: 3 },
670 Token::U8(1),
671 Token::U8(2),
672 Token::U8(3),
673 Token::TupleEnd,
674 ],
675 "data did not match any variant of untagged enum Untagged",
676 );
677 }
678
679 #[test]
test_internally_tagged_enum()680 fn test_internally_tagged_enum() {
681 #[derive(Debug, PartialEq, Serialize, Deserialize)]
682 struct Newtype(BTreeMap<String, String>);
683
684 #[derive(Debug, PartialEq, Serialize, Deserialize)]
685 struct Struct {
686 f: u8,
687 }
688
689 #[derive(Debug, PartialEq, Serialize, Deserialize)]
690 #[serde(tag = "type")]
691 enum InternallyTagged {
692 A { a: u8 },
693 B,
694 C(BTreeMap<String, String>),
695 D(Newtype),
696 E(Struct),
697 }
698
699 assert_tokens(
700 &InternallyTagged::A { a: 1 },
701 &[
702 Token::Struct {
703 name: "InternallyTagged",
704 len: 2,
705 },
706 Token::Str("type"),
707 Token::Str("A"),
708 Token::Str("a"),
709 Token::U8(1),
710 Token::StructEnd,
711 ],
712 );
713
714 assert_de_tokens(
715 &InternallyTagged::A { a: 1 },
716 &[
717 Token::Seq { len: Some(2) },
718 Token::Str("A"),
719 Token::U8(1),
720 Token::SeqEnd,
721 ],
722 );
723
724 assert_tokens(
725 &InternallyTagged::B,
726 &[
727 Token::Struct {
728 name: "InternallyTagged",
729 len: 1,
730 },
731 Token::Str("type"),
732 Token::Str("B"),
733 Token::StructEnd,
734 ],
735 );
736
737 assert_de_tokens(
738 &InternallyTagged::B,
739 &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd],
740 );
741
742 assert_tokens(
743 &InternallyTagged::C(BTreeMap::new()),
744 &[
745 Token::Map { len: Some(1) },
746 Token::Str("type"),
747 Token::Str("C"),
748 Token::MapEnd,
749 ],
750 );
751
752 assert_de_tokens_error::<InternallyTagged>(
753 &[
754 Token::Seq { len: Some(2) },
755 Token::Str("C"),
756 Token::Map { len: Some(0) },
757 Token::MapEnd,
758 Token::SeqEnd,
759 ],
760 "invalid type: sequence, expected a map",
761 );
762
763 assert_tokens(
764 &InternallyTagged::D(Newtype(BTreeMap::new())),
765 &[
766 Token::Map { len: Some(1) },
767 Token::Str("type"),
768 Token::Str("D"),
769 Token::MapEnd,
770 ],
771 );
772
773 assert_tokens(
774 &InternallyTagged::E(Struct { f: 6 }),
775 &[
776 Token::Struct {
777 name: "Struct",
778 len: 2,
779 },
780 Token::Str("type"),
781 Token::Str("E"),
782 Token::Str("f"),
783 Token::U8(6),
784 Token::StructEnd,
785 ],
786 );
787
788 assert_de_tokens(
789 &InternallyTagged::E(Struct { f: 6 }),
790 &[
791 Token::Seq { len: Some(2) },
792 Token::Str("E"),
793 Token::U8(6),
794 Token::SeqEnd,
795 ],
796 );
797
798 assert_de_tokens_error::<InternallyTagged>(
799 &[Token::Map { len: Some(0) }, Token::MapEnd],
800 "missing field `type`",
801 );
802
803 assert_de_tokens_error::<InternallyTagged>(
804 &[
805 Token::Map { len: Some(1) },
806 Token::Str("type"),
807 Token::Str("Z"),
808 Token::MapEnd,
809 ],
810 "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`",
811 );
812 }
813
814 #[test]
test_internally_tagged_bytes()815 fn test_internally_tagged_bytes() {
816 #[derive(Debug, PartialEq, Deserialize)]
817 #[serde(tag = "type")]
818 enum InternallyTagged {
819 String {
820 string: String,
821 },
822 Bytes {
823 #[serde(with = "bytes")]
824 bytes: Vec<u8>,
825 },
826 }
827
828 assert_de_tokens(
829 &InternallyTagged::String {
830 string: "\0".to_owned(),
831 },
832 &[
833 Token::Struct {
834 name: "String",
835 len: 2,
836 },
837 Token::Str("type"),
838 Token::Str("String"),
839 Token::Str("string"),
840 Token::Str("\0"),
841 Token::StructEnd,
842 ],
843 );
844
845 assert_de_tokens(
846 &InternallyTagged::String {
847 string: "\0".to_owned(),
848 },
849 &[
850 Token::Struct {
851 name: "String",
852 len: 2,
853 },
854 Token::Str("type"),
855 Token::Str("String"),
856 Token::Str("string"),
857 Token::String("\0"),
858 Token::StructEnd,
859 ],
860 );
861
862 assert_de_tokens(
863 &InternallyTagged::String {
864 string: "\0".to_owned(),
865 },
866 &[
867 Token::Struct {
868 name: "String",
869 len: 2,
870 },
871 Token::Str("type"),
872 Token::Str("String"),
873 Token::Str("string"),
874 Token::Bytes(b"\0"),
875 Token::StructEnd,
876 ],
877 );
878
879 assert_de_tokens(
880 &InternallyTagged::String {
881 string: "\0".to_owned(),
882 },
883 &[
884 Token::Struct {
885 name: "String",
886 len: 2,
887 },
888 Token::Str("type"),
889 Token::Str("String"),
890 Token::Str("string"),
891 Token::ByteBuf(b"\0"),
892 Token::StructEnd,
893 ],
894 );
895
896 assert_de_tokens(
897 &InternallyTagged::Bytes { bytes: vec![0] },
898 &[
899 Token::Struct {
900 name: "Bytes",
901 len: 2,
902 },
903 Token::Str("type"),
904 Token::Str("Bytes"),
905 Token::Str("bytes"),
906 Token::Str("\0"),
907 Token::StructEnd,
908 ],
909 );
910
911 assert_de_tokens(
912 &InternallyTagged::Bytes { bytes: vec![0] },
913 &[
914 Token::Struct {
915 name: "Bytes",
916 len: 2,
917 },
918 Token::Str("type"),
919 Token::Str("Bytes"),
920 Token::Str("bytes"),
921 Token::String("\0"),
922 Token::StructEnd,
923 ],
924 );
925
926 assert_de_tokens(
927 &InternallyTagged::Bytes { bytes: vec![0] },
928 &[
929 Token::Struct {
930 name: "Bytes",
931 len: 2,
932 },
933 Token::Str("type"),
934 Token::Str("Bytes"),
935 Token::Str("bytes"),
936 Token::Bytes(b"\0"),
937 Token::StructEnd,
938 ],
939 );
940
941 assert_de_tokens(
942 &InternallyTagged::Bytes { bytes: vec![0] },
943 &[
944 Token::Struct {
945 name: "Bytes",
946 len: 2,
947 },
948 Token::Str("type"),
949 Token::Str("Bytes"),
950 Token::Str("bytes"),
951 Token::ByteBuf(b"\0"),
952 Token::StructEnd,
953 ],
954 );
955
956 assert_de_tokens(
957 &InternallyTagged::Bytes { bytes: vec![0] },
958 &[
959 Token::Struct {
960 name: "Bytes",
961 len: 2,
962 },
963 Token::Str("type"),
964 Token::Str("Bytes"),
965 Token::Str("bytes"),
966 Token::Seq { len: Some(1) },
967 Token::U8(0),
968 Token::SeqEnd,
969 Token::StructEnd,
970 ],
971 );
972 }
973
974 #[test]
test_internally_tagged_struct_variant_containing_unit_variant()975 fn test_internally_tagged_struct_variant_containing_unit_variant() {
976 #[derive(Debug, PartialEq, Serialize, Deserialize)]
977 pub enum Level {
978 Info,
979 }
980
981 #[derive(Debug, PartialEq, Serialize, Deserialize)]
982 #[serde(tag = "action")]
983 pub enum Message {
984 Log { level: Level },
985 }
986
987 assert_de_tokens(
988 &Message::Log { level: Level::Info },
989 &[
990 Token::Struct {
991 name: "Message",
992 len: 2,
993 },
994 Token::Str("action"),
995 Token::Str("Log"),
996 Token::Str("level"),
997 Token::BorrowedStr("Info"),
998 Token::StructEnd,
999 ],
1000 );
1001
1002 assert_de_tokens(
1003 &Message::Log { level: Level::Info },
1004 &[
1005 Token::Map { len: Some(2) },
1006 Token::Str("action"),
1007 Token::Str("Log"),
1008 Token::Str("level"),
1009 Token::BorrowedStr("Info"),
1010 Token::MapEnd,
1011 ],
1012 );
1013
1014 assert_de_tokens(
1015 &Message::Log { level: Level::Info },
1016 &[
1017 Token::Seq { len: Some(2) },
1018 Token::Str("Log"),
1019 Token::BorrowedStr("Info"),
1020 Token::SeqEnd,
1021 ],
1022 );
1023 }
1024
1025 #[test]
test_internally_tagged_borrow()1026 fn test_internally_tagged_borrow() {
1027 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1028 #[serde(tag = "type")]
1029 pub enum Input<'a> {
1030 Package { name: &'a str },
1031 }
1032
1033 assert_tokens(
1034 &Input::Package { name: "borrowed" },
1035 &[
1036 Token::Struct {
1037 name: "Input",
1038 len: 2,
1039 },
1040 Token::BorrowedStr("type"),
1041 Token::BorrowedStr("Package"),
1042 Token::BorrowedStr("name"),
1043 Token::BorrowedStr("borrowed"),
1044 Token::StructEnd,
1045 ],
1046 );
1047 }
1048
1049 #[test]
test_adjacently_tagged_enum()1050 fn test_adjacently_tagged_enum() {
1051 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1052 #[serde(tag = "t", content = "c")]
1053 enum AdjacentlyTagged<T> {
1054 Unit,
1055 Newtype(T),
1056 Tuple(u8, u8),
1057 Struct { f: u8 },
1058 }
1059
1060 // unit with no content
1061 assert_ser_tokens(
1062 &AdjacentlyTagged::Unit::<u8>,
1063 &[
1064 Token::Struct {
1065 name: "AdjacentlyTagged",
1066 len: 1,
1067 },
1068 Token::Str("t"),
1069 Token::Str("Unit"),
1070 Token::StructEnd,
1071 ],
1072 );
1073
1074 // unit with no content
1075 assert_de_tokens(
1076 &AdjacentlyTagged::Unit::<u8>,
1077 &[
1078 Token::Struct {
1079 name: "AdjacentlyTagged",
1080 len: 2,
1081 },
1082 Token::Str("t"),
1083 Token::Str("Unit"),
1084 Token::StructEnd,
1085 ],
1086 );
1087
1088 // unit with tag first
1089 assert_de_tokens(
1090 &AdjacentlyTagged::Unit::<u8>,
1091 &[
1092 Token::Struct {
1093 name: "AdjacentlyTagged",
1094 len: 2,
1095 },
1096 Token::Str("t"),
1097 Token::Str("Unit"),
1098 Token::Str("c"),
1099 Token::Unit,
1100 Token::StructEnd,
1101 ],
1102 );
1103
1104 // unit with content first
1105 assert_de_tokens(
1106 &AdjacentlyTagged::Unit::<u8>,
1107 &[
1108 Token::Struct {
1109 name: "AdjacentlyTagged",
1110 len: 2,
1111 },
1112 Token::Str("c"),
1113 Token::Unit,
1114 Token::Str("t"),
1115 Token::Str("Unit"),
1116 Token::StructEnd,
1117 ],
1118 );
1119
1120 // unit with excess content (f, g, h)
1121 assert_de_tokens(
1122 &AdjacentlyTagged::Unit::<u8>,
1123 &[
1124 Token::Struct {
1125 name: "AdjacentlyTagged",
1126 len: 2,
1127 },
1128 Token::Str("f"),
1129 Token::Unit,
1130 Token::Str("t"),
1131 Token::Str("Unit"),
1132 Token::Str("g"),
1133 Token::Unit,
1134 Token::Str("c"),
1135 Token::Unit,
1136 Token::Str("h"),
1137 Token::Unit,
1138 Token::StructEnd,
1139 ],
1140 );
1141
1142 // newtype with tag first
1143 assert_tokens(
1144 &AdjacentlyTagged::Newtype::<u8>(1),
1145 &[
1146 Token::Struct {
1147 name: "AdjacentlyTagged",
1148 len: 2,
1149 },
1150 Token::Str("t"),
1151 Token::Str("Newtype"),
1152 Token::Str("c"),
1153 Token::U8(1),
1154 Token::StructEnd,
1155 ],
1156 );
1157
1158 // newtype with content first
1159 assert_de_tokens(
1160 &AdjacentlyTagged::Newtype::<u8>(1),
1161 &[
1162 Token::Struct {
1163 name: "AdjacentlyTagged",
1164 len: 2,
1165 },
1166 Token::Str("c"),
1167 Token::U8(1),
1168 Token::Str("t"),
1169 Token::Str("Newtype"),
1170 Token::StructEnd,
1171 ],
1172 );
1173
1174 // optional newtype with no content field
1175 assert_de_tokens(
1176 &AdjacentlyTagged::Newtype::<Option<u8>>(None),
1177 &[
1178 Token::Struct {
1179 name: "AdjacentlyTagged",
1180 len: 1,
1181 },
1182 Token::Str("t"),
1183 Token::Str("Newtype"),
1184 Token::StructEnd,
1185 ],
1186 );
1187
1188 // tuple with tag first
1189 assert_tokens(
1190 &AdjacentlyTagged::Tuple::<u8>(1, 1),
1191 &[
1192 Token::Struct {
1193 name: "AdjacentlyTagged",
1194 len: 2,
1195 },
1196 Token::Str("t"),
1197 Token::Str("Tuple"),
1198 Token::Str("c"),
1199 Token::Tuple { len: 2 },
1200 Token::U8(1),
1201 Token::U8(1),
1202 Token::TupleEnd,
1203 Token::StructEnd,
1204 ],
1205 );
1206
1207 // tuple with content first
1208 assert_de_tokens(
1209 &AdjacentlyTagged::Tuple::<u8>(1, 1),
1210 &[
1211 Token::Struct {
1212 name: "AdjacentlyTagged",
1213 len: 2,
1214 },
1215 Token::Str("c"),
1216 Token::Tuple { len: 2 },
1217 Token::U8(1),
1218 Token::U8(1),
1219 Token::TupleEnd,
1220 Token::Str("t"),
1221 Token::Str("Tuple"),
1222 Token::StructEnd,
1223 ],
1224 );
1225
1226 // struct with tag first
1227 assert_tokens(
1228 &AdjacentlyTagged::Struct::<u8> { f: 1 },
1229 &[
1230 Token::Struct {
1231 name: "AdjacentlyTagged",
1232 len: 2,
1233 },
1234 Token::Str("t"),
1235 Token::Str("Struct"),
1236 Token::Str("c"),
1237 Token::Struct {
1238 name: "Struct",
1239 len: 1,
1240 },
1241 Token::Str("f"),
1242 Token::U8(1),
1243 Token::StructEnd,
1244 Token::StructEnd,
1245 ],
1246 );
1247
1248 // struct with content first
1249 assert_de_tokens(
1250 &AdjacentlyTagged::Struct::<u8> { f: 1 },
1251 &[
1252 Token::Struct {
1253 name: "AdjacentlyTagged",
1254 len: 2,
1255 },
1256 Token::Str("c"),
1257 Token::Struct {
1258 name: "Struct",
1259 len: 1,
1260 },
1261 Token::Str("f"),
1262 Token::U8(1),
1263 Token::StructEnd,
1264 Token::Str("t"),
1265 Token::Str("Struct"),
1266 Token::StructEnd,
1267 ],
1268 );
1269 }
1270
1271 #[test]
test_adjacently_tagged_enum_deny_unknown_fields()1272 fn test_adjacently_tagged_enum_deny_unknown_fields() {
1273 #[derive(Debug, PartialEq, Deserialize)]
1274 #[serde(tag = "t", content = "c", deny_unknown_fields)]
1275 enum AdjacentlyTagged {
1276 Unit,
1277 }
1278
1279 assert_de_tokens(
1280 &AdjacentlyTagged::Unit,
1281 &[
1282 Token::Struct {
1283 name: "AdjacentlyTagged",
1284 len: 2,
1285 },
1286 Token::Str("t"),
1287 Token::Str("Unit"),
1288 Token::Str("c"),
1289 Token::Unit,
1290 Token::StructEnd,
1291 ],
1292 );
1293
1294 assert_de_tokens_error::<AdjacentlyTagged>(
1295 &[
1296 Token::Struct {
1297 name: "AdjacentlyTagged",
1298 len: 2,
1299 },
1300 Token::Str("t"),
1301 Token::Str("Unit"),
1302 Token::Str("c"),
1303 Token::Unit,
1304 Token::Str("h"),
1305 ],
1306 r#"invalid value: string "h", expected "t" or "c""#,
1307 );
1308
1309 assert_de_tokens_error::<AdjacentlyTagged>(
1310 &[
1311 Token::Struct {
1312 name: "AdjacentlyTagged",
1313 len: 2,
1314 },
1315 Token::Str("h"),
1316 ],
1317 r#"invalid value: string "h", expected "t" or "c""#,
1318 );
1319
1320 assert_de_tokens_error::<AdjacentlyTagged>(
1321 &[
1322 Token::Struct {
1323 name: "AdjacentlyTagged",
1324 len: 2,
1325 },
1326 Token::Str("c"),
1327 Token::Unit,
1328 Token::Str("h"),
1329 ],
1330 r#"invalid value: string "h", expected "t" or "c""#,
1331 );
1332 }
1333
1334 #[test]
test_enum_in_internally_tagged_enum()1335 fn test_enum_in_internally_tagged_enum() {
1336 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1337 #[serde(tag = "type")]
1338 enum Outer {
1339 Inner(Inner),
1340 }
1341
1342 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1343 enum Inner {
1344 Unit,
1345 Newtype(u8),
1346 Tuple(u8, u8),
1347 Struct { f: u8 },
1348 }
1349
1350 assert_tokens(
1351 &Outer::Inner(Inner::Unit),
1352 &[
1353 Token::Map { len: Some(2) },
1354 Token::Str("type"),
1355 Token::Str("Inner"),
1356 Token::Str("Unit"),
1357 Token::Unit,
1358 Token::MapEnd,
1359 ],
1360 );
1361
1362 assert_tokens(
1363 &Outer::Inner(Inner::Newtype(1)),
1364 &[
1365 Token::Map { len: Some(2) },
1366 Token::Str("type"),
1367 Token::Str("Inner"),
1368 Token::Str("Newtype"),
1369 Token::U8(1),
1370 Token::MapEnd,
1371 ],
1372 );
1373
1374 assert_tokens(
1375 &Outer::Inner(Inner::Tuple(1, 1)),
1376 &[
1377 Token::Map { len: Some(2) },
1378 Token::Str("type"),
1379 Token::Str("Inner"),
1380 Token::Str("Tuple"),
1381 Token::TupleStruct {
1382 name: "Tuple",
1383 len: 2,
1384 },
1385 Token::U8(1),
1386 Token::U8(1),
1387 Token::TupleStructEnd,
1388 Token::MapEnd,
1389 ],
1390 );
1391
1392 assert_tokens(
1393 &Outer::Inner(Inner::Struct { f: 1 }),
1394 &[
1395 Token::Map { len: Some(2) },
1396 Token::Str("type"),
1397 Token::Str("Inner"),
1398 Token::Str("Struct"),
1399 Token::Struct {
1400 name: "Struct",
1401 len: 1,
1402 },
1403 Token::Str("f"),
1404 Token::U8(1),
1405 Token::StructEnd,
1406 Token::MapEnd,
1407 ],
1408 );
1409 }
1410
1411 #[test]
test_internally_tagged_struct()1412 fn test_internally_tagged_struct() {
1413 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1414 #[serde(tag = "type")]
1415 pub struct Struct {
1416 a: u8,
1417 }
1418
1419 assert_tokens(
1420 &Struct { a: 1 },
1421 &[
1422 Token::Struct {
1423 name: "Struct",
1424 len: 2,
1425 },
1426 Token::Str("type"),
1427 Token::Str("Struct"),
1428 Token::Str("a"),
1429 Token::U8(1),
1430 Token::StructEnd,
1431 ],
1432 );
1433
1434 assert_de_tokens(
1435 &Struct { a: 1 },
1436 &[
1437 Token::Struct {
1438 name: "Struct",
1439 len: 1,
1440 },
1441 Token::Str("a"),
1442 Token::U8(1),
1443 Token::StructEnd,
1444 ],
1445 );
1446 }
1447
1448 #[test]
test_internally_tagged_braced_struct_with_zero_fields()1449 fn test_internally_tagged_braced_struct_with_zero_fields() {
1450 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1451 #[serde(tag = "type")]
1452 struct S {}
1453
1454 assert_tokens(
1455 &S {},
1456 &[
1457 Token::Struct { name: "S", len: 1 },
1458 Token::Str("type"),
1459 Token::Str("S"),
1460 Token::StructEnd,
1461 ],
1462 );
1463 }
1464
1465 #[test]
test_internally_tagged_struct_with_flattened_field()1466 fn test_internally_tagged_struct_with_flattened_field() {
1467 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1468 #[serde(tag = "tag_struct")]
1469 pub struct Struct {
1470 #[serde(flatten)]
1471 pub flat: Enum,
1472 }
1473
1474 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1475 #[serde(tag = "tag_enum", content = "content")]
1476 pub enum Enum {
1477 A(u64),
1478 }
1479
1480 assert_tokens(
1481 &Struct { flat: Enum::A(0) },
1482 &[
1483 Token::Map { len: None },
1484 Token::Str("tag_struct"),
1485 Token::Str("Struct"),
1486 Token::Str("tag_enum"),
1487 Token::Str("A"),
1488 Token::Str("content"),
1489 Token::U64(0),
1490 Token::MapEnd,
1491 ],
1492 );
1493
1494 assert_de_tokens(
1495 &Struct { flat: Enum::A(0) },
1496 &[
1497 Token::Map { len: None },
1498 Token::Str("tag_enum"),
1499 Token::Str("A"),
1500 Token::Str("content"),
1501 Token::U64(0),
1502 Token::MapEnd,
1503 ],
1504 );
1505 }
1506
1507 #[test]
test_untagged_enum_with_flattened_integer_key()1508 fn test_untagged_enum_with_flattened_integer_key() {
1509 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1510 #[serde(untagged)]
1511 pub enum Untagged {
1512 Variant {
1513 #[serde(flatten)]
1514 map: BTreeMap<u64, String>,
1515 },
1516 }
1517
1518 assert_tokens(
1519 &Untagged::Variant {
1520 map: {
1521 let mut map = BTreeMap::new();
1522 map.insert(100, "BTreeMap".to_owned());
1523 map
1524 },
1525 },
1526 &[
1527 Token::Map { len: None },
1528 Token::U64(100),
1529 Token::Str("BTreeMap"),
1530 Token::MapEnd,
1531 ],
1532 );
1533 }
1534
1535 #[test]
test_enum_in_untagged_enum()1536 fn test_enum_in_untagged_enum() {
1537 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1538 #[serde(untagged)]
1539 enum Outer {
1540 Inner(Inner),
1541 }
1542
1543 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1544 enum Inner {
1545 Unit,
1546 Newtype(u8),
1547 Tuple(u8, u8),
1548 Struct { f: u8 },
1549 }
1550
1551 assert_tokens(
1552 &Outer::Inner(Inner::Unit),
1553 &[Token::UnitVariant {
1554 name: "Inner",
1555 variant: "Unit",
1556 }],
1557 );
1558
1559 assert_tokens(
1560 &Outer::Inner(Inner::Newtype(1)),
1561 &[
1562 Token::NewtypeVariant {
1563 name: "Inner",
1564 variant: "Newtype",
1565 },
1566 Token::U8(1),
1567 ],
1568 );
1569
1570 assert_tokens(
1571 &Outer::Inner(Inner::Tuple(1, 1)),
1572 &[
1573 Token::TupleVariant {
1574 name: "Inner",
1575 variant: "Tuple",
1576 len: 2,
1577 },
1578 Token::U8(1),
1579 Token::U8(1),
1580 Token::TupleVariantEnd,
1581 ],
1582 );
1583
1584 assert_tokens(
1585 &Outer::Inner(Inner::Struct { f: 1 }),
1586 &[
1587 Token::StructVariant {
1588 name: "Inner",
1589 variant: "Struct",
1590 len: 1,
1591 },
1592 Token::Str("f"),
1593 Token::U8(1),
1594 Token::StructVariantEnd,
1595 ],
1596 );
1597 }
1598
1599 #[test]
test_untagged_bytes()1600 fn test_untagged_bytes() {
1601 #[derive(Debug, PartialEq, Deserialize)]
1602 #[serde(untagged)]
1603 enum Untagged {
1604 String {
1605 string: String,
1606 },
1607 Bytes {
1608 #[serde(with = "bytes")]
1609 bytes: Vec<u8>,
1610 },
1611 }
1612
1613 assert_de_tokens(
1614 &Untagged::String {
1615 string: "\0".to_owned(),
1616 },
1617 &[
1618 Token::Struct {
1619 name: "Untagged",
1620 len: 1,
1621 },
1622 Token::Str("string"),
1623 Token::Str("\0"),
1624 Token::StructEnd,
1625 ],
1626 );
1627
1628 assert_de_tokens(
1629 &Untagged::String {
1630 string: "\0".to_owned(),
1631 },
1632 &[
1633 Token::Struct {
1634 name: "Untagged",
1635 len: 1,
1636 },
1637 Token::Str("string"),
1638 Token::String("\0"),
1639 Token::StructEnd,
1640 ],
1641 );
1642
1643 assert_de_tokens(
1644 &Untagged::String {
1645 string: "\0".to_owned(),
1646 },
1647 &[
1648 Token::Struct {
1649 name: "Untagged",
1650 len: 1,
1651 },
1652 Token::Str("string"),
1653 Token::Bytes(b"\0"),
1654 Token::StructEnd,
1655 ],
1656 );
1657
1658 assert_de_tokens(
1659 &Untagged::String {
1660 string: "\0".to_owned(),
1661 },
1662 &[
1663 Token::Struct {
1664 name: "Untagged",
1665 len: 1,
1666 },
1667 Token::Str("string"),
1668 Token::ByteBuf(b"\0"),
1669 Token::StructEnd,
1670 ],
1671 );
1672
1673 assert_de_tokens(
1674 &Untagged::Bytes { bytes: vec![0] },
1675 &[
1676 Token::Struct {
1677 name: "Untagged",
1678 len: 1,
1679 },
1680 Token::Str("bytes"),
1681 Token::Str("\0"),
1682 Token::StructEnd,
1683 ],
1684 );
1685
1686 assert_de_tokens(
1687 &Untagged::Bytes { bytes: vec![0] },
1688 &[
1689 Token::Struct {
1690 name: "Untagged",
1691 len: 1,
1692 },
1693 Token::Str("bytes"),
1694 Token::String("\0"),
1695 Token::StructEnd,
1696 ],
1697 );
1698
1699 assert_de_tokens(
1700 &Untagged::Bytes { bytes: vec![0] },
1701 &[
1702 Token::Struct {
1703 name: "Untagged",
1704 len: 1,
1705 },
1706 Token::Str("bytes"),
1707 Token::Bytes(b"\0"),
1708 Token::StructEnd,
1709 ],
1710 );
1711
1712 assert_de_tokens(
1713 &Untagged::Bytes { bytes: vec![0] },
1714 &[
1715 Token::Struct {
1716 name: "Untagged",
1717 len: 1,
1718 },
1719 Token::Str("bytes"),
1720 Token::ByteBuf(b"\0"),
1721 Token::StructEnd,
1722 ],
1723 );
1724
1725 assert_de_tokens(
1726 &Untagged::Bytes { bytes: vec![0] },
1727 &[
1728 Token::Struct {
1729 name: "Untagged",
1730 len: 1,
1731 },
1732 Token::Str("bytes"),
1733 Token::Seq { len: Some(1) },
1734 Token::U8(0),
1735 Token::SeqEnd,
1736 Token::StructEnd,
1737 ],
1738 );
1739 }
1740
1741 #[test]
test_rename_all()1742 fn test_rename_all() {
1743 #[derive(Serialize, Deserialize, Debug, PartialEq)]
1744 #[serde(rename_all = "snake_case")]
1745 enum E {
1746 #[serde(rename_all = "camelCase")]
1747 Serialize {
1748 serialize: bool,
1749 serialize_seq: bool,
1750 },
1751 #[serde(rename_all = "kebab-case")]
1752 SerializeSeq {
1753 serialize: bool,
1754 serialize_seq: bool,
1755 },
1756 #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1757 SerializeMap {
1758 serialize: bool,
1759 serialize_seq: bool,
1760 },
1761 }
1762
1763 #[derive(Serialize, Deserialize, Debug, PartialEq)]
1764 #[serde(rename_all = "PascalCase")]
1765 struct S {
1766 serialize: bool,
1767 serialize_seq: bool,
1768 }
1769
1770 #[derive(Serialize, Deserialize, Debug, PartialEq)]
1771 #[serde(rename_all = "SCREAMING-KEBAB-CASE")]
1772 struct ScreamingKebab {
1773 serialize: bool,
1774 serialize_seq: bool,
1775 }
1776
1777 assert_tokens(
1778 &E::Serialize {
1779 serialize: true,
1780 serialize_seq: true,
1781 },
1782 &[
1783 Token::StructVariant {
1784 name: "E",
1785 variant: "serialize",
1786 len: 2,
1787 },
1788 Token::Str("serialize"),
1789 Token::Bool(true),
1790 Token::Str("serializeSeq"),
1791 Token::Bool(true),
1792 Token::StructVariantEnd,
1793 ],
1794 );
1795
1796 assert_tokens(
1797 &E::SerializeSeq {
1798 serialize: true,
1799 serialize_seq: true,
1800 },
1801 &[
1802 Token::StructVariant {
1803 name: "E",
1804 variant: "serialize_seq",
1805 len: 2,
1806 },
1807 Token::Str("serialize"),
1808 Token::Bool(true),
1809 Token::Str("serialize-seq"),
1810 Token::Bool(true),
1811 Token::StructVariantEnd,
1812 ],
1813 );
1814
1815 assert_tokens(
1816 &E::SerializeMap {
1817 serialize: true,
1818 serialize_seq: true,
1819 },
1820 &[
1821 Token::StructVariant {
1822 name: "E",
1823 variant: "serialize_map",
1824 len: 2,
1825 },
1826 Token::Str("SERIALIZE"),
1827 Token::Bool(true),
1828 Token::Str("SERIALIZE_SEQ"),
1829 Token::Bool(true),
1830 Token::StructVariantEnd,
1831 ],
1832 );
1833
1834 assert_tokens(
1835 &S {
1836 serialize: true,
1837 serialize_seq: true,
1838 },
1839 &[
1840 Token::Struct { name: "S", len: 2 },
1841 Token::Str("Serialize"),
1842 Token::Bool(true),
1843 Token::Str("SerializeSeq"),
1844 Token::Bool(true),
1845 Token::StructEnd,
1846 ],
1847 );
1848
1849 assert_tokens(
1850 &ScreamingKebab {
1851 serialize: true,
1852 serialize_seq: true,
1853 },
1854 &[
1855 Token::Struct {
1856 name: "ScreamingKebab",
1857 len: 2,
1858 },
1859 Token::Str("SERIALIZE"),
1860 Token::Bool(true),
1861 Token::Str("SERIALIZE-SEQ"),
1862 Token::Bool(true),
1863 Token::StructEnd,
1864 ],
1865 );
1866 }
1867
1868 #[test]
test_untagged_newtype_variant_containing_unit_struct_not_map()1869 fn test_untagged_newtype_variant_containing_unit_struct_not_map() {
1870 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1871 struct Unit;
1872
1873 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1874 #[serde(untagged)]
1875 enum Message {
1876 Unit(Unit),
1877 Map(BTreeMap<String, String>),
1878 }
1879
1880 assert_tokens(
1881 &Message::Map(BTreeMap::new()),
1882 &[Token::Map { len: Some(0) }, Token::MapEnd],
1883 );
1884 }
1885
1886 #[test]
test_internally_tagged_newtype_variant_containing_unit_struct()1887 fn test_internally_tagged_newtype_variant_containing_unit_struct() {
1888 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1889 struct Info;
1890
1891 #[derive(Debug, PartialEq, Serialize, Deserialize)]
1892 #[serde(tag = "topic")]
1893 enum Message {
1894 Info(Info),
1895 }
1896
1897 assert_tokens(
1898 &Message::Info(Info),
1899 &[
1900 Token::Map { len: Some(1) },
1901 Token::Str("topic"),
1902 Token::Str("Info"),
1903 Token::MapEnd,
1904 ],
1905 );
1906
1907 assert_de_tokens(
1908 &Message::Info(Info),
1909 &[
1910 Token::Struct {
1911 name: "Message",
1912 len: 1,
1913 },
1914 Token::Str("topic"),
1915 Token::Str("Info"),
1916 Token::StructEnd,
1917 ],
1918 );
1919
1920 assert_de_tokens(
1921 &Message::Info(Info),
1922 &[
1923 Token::Seq { len: Some(1) },
1924 Token::Str("Info"),
1925 Token::SeqEnd,
1926 ],
1927 );
1928 }
1929
1930 #[deny(unaligned_references)]
1931 #[test]
test_packed_struct_can_derive_serialize()1932 fn test_packed_struct_can_derive_serialize() {
1933 #[derive(Copy, Clone, Serialize)]
1934 #[repr(packed, C)]
1935 struct PackedC {
1936 t: f32,
1937 }
1938
1939 #[derive(Copy, Clone, Serialize)]
1940 #[repr(C, packed)]
1941 struct CPacked {
1942 t: f32,
1943 }
1944
1945 #[derive(Copy, Clone, Serialize)]
1946 #[repr(C, packed(2))]
1947 struct CPacked2 {
1948 t: f32,
1949 }
1950
1951 #[derive(Copy, Clone, Serialize)]
1952 #[repr(packed(2), C)]
1953 struct Packed2C {
1954 t: f32,
1955 }
1956 }
1957