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