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