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
13 use serde::de::{self, Deserialize, Deserializer, IgnoredAny, MapAccess, Unexpected, Visitor};
14 use serde::ser::{Serialize, Serializer};
15 use serde_derive::{Deserialize, Serialize};
16 use serde_test::{
17 assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
18 assert_tokens, Token,
19 };
20 use std::collections::{BTreeMap, HashMap};
21 use std::convert::TryFrom;
22 use std::fmt;
23 use std::marker::PhantomData;
24
25 trait MyDefault: Sized {
my_default() -> Self26 fn my_default() -> Self;
27 }
28
29 trait ShouldSkip: Sized {
should_skip(&self) -> bool30 fn should_skip(&self) -> bool;
31 }
32
33 trait SerializeWith: Sized {
serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> where S: Serializer34 fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer;
37 }
38
39 trait DeserializeWith: Sized {
deserialize_with<'de, D>(de: D) -> Result<Self, D::Error> where D: Deserializer<'de>40 fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
41 where
42 D: Deserializer<'de>;
43 }
44
45 impl MyDefault for i32 {
my_default() -> Self46 fn my_default() -> Self {
47 123
48 }
49 }
50
51 impl ShouldSkip for i32 {
should_skip(&self) -> bool52 fn should_skip(&self) -> bool {
53 *self == 123
54 }
55 }
56
57 impl SerializeWith for i32 {
serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> where S: Serializer,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
70 impl DeserializeWith for i32 {
deserialize_with<'de, D>(de: D) -> Result<Self, D::Error> where D: Deserializer<'de>,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)]
84 struct DefaultStruct<A, B, C, D, E>
85 where
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)]
101 struct DefaultTupleStruct<A, B, C>(
102 A,
103 #[serde(default)] B,
104 #[serde(default = "MyDefault::my_default")] C,
105 )
106 where
107 C: MyDefault;
108
109 #[derive(Debug, PartialEq, Serialize, Deserialize)]
110 struct CollectOther {
111 a: u32,
112 b: u32,
113 #[serde(flatten)]
114 extra: HashMap<String, u32>,
115 }
116
117 #[test]
test_default_struct()118 fn 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]
test_default_tuple()167 fn 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)]
196 enum DefaultStructVariant<A, B, C, D, E>
197 where
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)]
215 enum DefaultTupleVariant<A, B, C>
216 where
217 C: MyDefault,
218 {
219 Tuple(
220 A,
221 #[serde(default)] B,
222 #[serde(default = "MyDefault::my_default")] C,
223 ),
224 }
225
226 #[test]
test_default_struct_variant()227 fn 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]
test_default_tuple_variant()278 fn 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)]
310 struct NoStdDefault(i8);
311
312 impl MyDefault for NoStdDefault {
my_default() -> Self313 fn my_default() -> Self {
314 NoStdDefault(123)
315 }
316 }
317
318 #[derive(Debug, PartialEq, Deserialize)]
319 struct 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]
test_no_std_default()327 fn 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)]
360 struct NotDeserializeStruct(i8);
361
362 impl Default for NotDeserializeStruct {
default() -> Self363 fn default() -> Self {
364 NotDeserializeStruct(123)
365 }
366 }
367
368 impl DeserializeWith for NotDeserializeStruct {
deserialize_with<'de, D>(_: D) -> Result<Self, D::Error> where D: Deserializer<'de>,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)]
379 enum NotDeserializeEnum {
380 Trouble,
381 }
382
383 impl MyDefault for NotDeserializeEnum {
my_default() -> Self384 fn my_default() -> Self {
385 NotDeserializeEnum::Trouble
386 }
387 }
388
389 #[derive(Debug, PartialEq, Deserialize)]
390 struct 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]
test_elt_not_deserialize()405 fn 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)]
425 struct DenyUnknown {
426 a1: i32,
427 }
428
429 #[test]
test_ignore_unknown()430 fn 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")]
479 struct 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"))]
487 struct 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)]
495 struct AliasStruct {
496 a1: i32,
497 #[serde(alias = "a3")]
498 a2: i32,
499 #[serde(alias = "a5", rename = "a6")]
500 a4: i32,
501 }
502
503 #[test]
test_rename_struct()504 fn 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]
test_unknown_field_rename_struct()594 fn 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")]
614 enum 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"))]
630 enum 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)]
642 enum 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]
test_rename_enum()654 fn 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]
test_unknown_field_rename_enum()778 fn 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)]
807 struct SkipSerializingStruct<'a, B, C>
808 where
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]
test_skip_serializing_struct()819 fn 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)]
855 struct SkipSerializingTupleStruct<'a, B, C>(
856 &'a i8,
857 #[serde(skip_serializing)] B,
858 #[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
859 )
860 where
861 C: ShouldSkip;
862
863 #[test]
test_skip_serializing_tuple_struct()864 fn 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)]
893 struct SkipStruct<B> {
894 a: i8,
895 #[serde(skip)]
896 b: B,
897 }
898
899 #[test]
test_skip_struct()900 fn 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)]
929 enum SkipSerializingEnum<'a, B, C>
930 where
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]
test_skip_serializing_enum()948 fn 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)]
1013 struct NotSerializeStruct(i8);
1014
1015 #[derive(Debug, PartialEq)]
1016 enum NotSerializeEnum {
1017 Trouble,
1018 }
1019
1020 impl SerializeWith for NotSerializeEnum {
serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error> where S: Serializer,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)]
1030 struct ContainsNotSerialize<'a, B, C, D>
1031 where
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]
test_elt_not_serialize()1045 fn 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)]
1070 struct SerializeWithStruct<'a, B>
1071 where
1072 B: SerializeWith,
1073 {
1074 a: &'a i8,
1075 #[serde(serialize_with = "SerializeWith::serialize_with")]
1076 b: B,
1077 }
1078
1079 #[test]
test_serialize_with_struct()1080 fn 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)]
1114 enum SerializeWithEnum<'a, B>
1115 where
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]
test_serialize_with_enum()1126 fn 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)]
1162 enum 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
serialize_unit_variant_as_i8<S>(serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,1180 fn serialize_unit_variant_as_i8<S>(serializer: S) -> Result<S::Ok, S::Error>
1181 where
1182 S: Serializer,
1183 {
1184 serializer.serialize_i8(0)
1185 }
1186
deserialize_i8_as_unit_variant<'de, D>(deserializer: D) -> Result<(), D::Error> where D: Deserializer<'de>,1187 fn deserialize_i8_as_unit_variant<'de, D>(deserializer: D) -> Result<(), D::Error>
1188 where
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
serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,1198 fn serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S::Ok, S::Error>
1199 where
1200 S: Serializer,
1201 {
1202 serializer.collect_str(&format_args!("{};{:?}", f1, f2))
1203 }
1204
deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error> where D: Deserializer<'de>,1205 fn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error>
1206 where
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]
test_serialize_with_variant()1227 fn 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]
test_deserialize_with_variant()1277 fn 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)]
1327 struct DeserializeWithStruct<B>
1328 where
1329 B: DeserializeWith,
1330 {
1331 a: i8,
1332 #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
1333 b: B,
1334 }
1335
1336 #[test]
test_deserialize_with_struct()1337 fn 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)]
1370 enum DeserializeWithEnum<B>
1371 where
1372 B: DeserializeWith,
1373 {
1374 Struct {
1375 a: i8,
1376 #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
1377 b: B,
1378 },
1379 }
1380
1381 #[test]
test_deserialize_with_enum()1382 fn 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]
test_missing_renamed_field_struct()1417 fn 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]
test_missing_renamed_field_enum()1446 fn 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)]
1475 enum InvalidLengthEnum {
1476 A(i32, i32, i32),
1477 B(#[serde(skip_deserializing)] i32, i32, i32),
1478 }
1479
1480 #[test]
test_invalid_length_enum()1481 fn 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")]
1510 struct StructFromEnum(Option<u32>);
1511
1512 impl Into<EnumToU32> for StructFromEnum {
into(self) -> EnumToU321513 fn into(self) -> EnumToU32 {
1514 match self {
1515 StructFromEnum(v) => v.into(),
1516 }
1517 }
1518 }
1519
1520 impl From<EnumToU32> for StructFromEnum {
from(v: EnumToU32) -> Self1521 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>")]
1528 enum EnumToU32 {
1529 One,
1530 Two,
1531 Three,
1532 Four,
1533 Nothing,
1534 }
1535
1536 impl Into<Option<u32>> for EnumToU32 {
into(self) -> Option<u32>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
1548 impl From<Option<u32>> for EnumToU32 {
from(v: Option<u32>) -> Self1549 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")]
1562 enum TryFromU32 {
1563 One,
1564 Two,
1565 }
1566
1567 impl TryFrom<u32> for TryFromU32 {
1568 type Error = String;
1569
try_from(value: u32) -> Result<Self, Self::Error>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]
test_from_into_traits()1580 fn 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]
test_collect_other()1592 fn 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]
test_unknown_field_in_flatten()1611 fn 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]
test_complex_flatten()1649 fn 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]
test_flatten_map_twice()1753 fn 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]
test_flatten_unit()1796 fn 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]
test_flatten_unsupported_type()1819 fn 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]
test_non_string_keys()1853 fn 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]
test_lifetime_propagation_for_flatten()1884 fn 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]
test_externally_tagged_enum_containing_flatten()1967 fn 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]
test_internally_tagged_enum_with_skipped_conflict()2005 fn 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]
test_internally_tagged_enum_containing_flatten()2038 fn 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]
test_internally_tagged_enum_new_type_with_unit()2075 fn 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]
test_adjacently_tagged_enum_bytes()2094 fn 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]
test_adjacently_tagged_enum_containing_flatten()2147 fn 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]
test_untagged_enum_containing_flatten()2193 fn 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]
test_partially_untagged_enum()2228 fn 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]
test_partially_untagged_enum_generic()2259 fn 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]
test_partially_untagged_enum_desugared()2298 fn 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]
test_partially_untagged_internally_tagged_enum()2384 fn 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]
test_partially_untagged_adjacently_tagged_enum()2414 fn 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]
test_flatten_option()2446 fn 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]
test_flatten_ignored_any()2516 fn 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]
test_transparent_struct()2541 fn 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]
test_transparent_tuple_struct()2565 fn 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]
test_internally_tagged_unit_enum_with_unknown_fields()2579 fn 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]
test_flatten_any_after_flatten_struct()2602 fn 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]
test_alias_in_flatten_context()2663 fn 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]
test_expecting_message()2725 fn 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]
test_expecting_message_externally_tagged_enum()2769 fn 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]
test_expecting_message_internally_tagged_enum()2789 fn 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]
test_expecting_message_adjacently_tagged_enum()2810 fn 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]
test_expecting_message_untagged_tagged_enum()2836 fn 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]
test_expecting_message_identifier_enum()2848 fn 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
2894 mod 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]
newtype()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]
tuple()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]
struct_from_seq()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]
struct_from_map()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]
struct_()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]
newtype()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]
structs()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]
unit_enum_with_unknown_fields()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]
struct_()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