• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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