17e2e9c0cSopenharmony_ci#![allow(
27e2e9c0cSopenharmony_ci    clippy::cast_lossless,
37e2e9c0cSopenharmony_ci    clippy::derive_partial_eq_without_eq,
47e2e9c0cSopenharmony_ci    clippy::from_over_into,
57e2e9c0cSopenharmony_ci    // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
67e2e9c0cSopenharmony_ci    clippy::nonstandard_macro_braces,
77e2e9c0cSopenharmony_ci    clippy::too_many_lines,
87e2e9c0cSopenharmony_ci    clippy::trivially_copy_pass_by_ref,
97e2e9c0cSopenharmony_ci    clippy::type_repetition_in_bounds,
107e2e9c0cSopenharmony_ci    clippy::uninlined_format_args,
117e2e9c0cSopenharmony_ci)]
127e2e9c0cSopenharmony_ci
137e2e9c0cSopenharmony_ciuse serde::de::{self, Deserialize, Deserializer, IgnoredAny, MapAccess, Unexpected, Visitor};
147e2e9c0cSopenharmony_ciuse serde::ser::{Serialize, Serializer};
157e2e9c0cSopenharmony_ciuse serde_derive::{Deserialize, Serialize};
167e2e9c0cSopenharmony_ciuse serde_test::{
177e2e9c0cSopenharmony_ci    assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
187e2e9c0cSopenharmony_ci    assert_tokens, Token,
197e2e9c0cSopenharmony_ci};
207e2e9c0cSopenharmony_ciuse std::collections::{BTreeMap, HashMap};
217e2e9c0cSopenharmony_ciuse std::convert::TryFrom;
227e2e9c0cSopenharmony_ciuse std::fmt;
237e2e9c0cSopenharmony_ciuse std::marker::PhantomData;
247e2e9c0cSopenharmony_ci
257e2e9c0cSopenharmony_citrait MyDefault: Sized {
267e2e9c0cSopenharmony_ci    fn my_default() -> Self;
277e2e9c0cSopenharmony_ci}
287e2e9c0cSopenharmony_ci
297e2e9c0cSopenharmony_citrait ShouldSkip: Sized {
307e2e9c0cSopenharmony_ci    fn should_skip(&self) -> bool;
317e2e9c0cSopenharmony_ci}
327e2e9c0cSopenharmony_ci
337e2e9c0cSopenharmony_citrait SerializeWith: Sized {
347e2e9c0cSopenharmony_ci    fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
357e2e9c0cSopenharmony_ci    where
367e2e9c0cSopenharmony_ci        S: Serializer;
377e2e9c0cSopenharmony_ci}
387e2e9c0cSopenharmony_ci
397e2e9c0cSopenharmony_citrait DeserializeWith: Sized {
407e2e9c0cSopenharmony_ci    fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
417e2e9c0cSopenharmony_ci    where
427e2e9c0cSopenharmony_ci        D: Deserializer<'de>;
437e2e9c0cSopenharmony_ci}
447e2e9c0cSopenharmony_ci
457e2e9c0cSopenharmony_ciimpl MyDefault for i32 {
467e2e9c0cSopenharmony_ci    fn my_default() -> Self {
477e2e9c0cSopenharmony_ci        123
487e2e9c0cSopenharmony_ci    }
497e2e9c0cSopenharmony_ci}
507e2e9c0cSopenharmony_ci
517e2e9c0cSopenharmony_ciimpl ShouldSkip for i32 {
527e2e9c0cSopenharmony_ci    fn should_skip(&self) -> bool {
537e2e9c0cSopenharmony_ci        *self == 123
547e2e9c0cSopenharmony_ci    }
557e2e9c0cSopenharmony_ci}
567e2e9c0cSopenharmony_ci
577e2e9c0cSopenharmony_ciimpl SerializeWith for i32 {
587e2e9c0cSopenharmony_ci    fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
597e2e9c0cSopenharmony_ci    where
607e2e9c0cSopenharmony_ci        S: Serializer,
617e2e9c0cSopenharmony_ci    {
627e2e9c0cSopenharmony_ci        if *self == 123 {
637e2e9c0cSopenharmony_ci            true.serialize(ser)
647e2e9c0cSopenharmony_ci        } else {
657e2e9c0cSopenharmony_ci            false.serialize(ser)
667e2e9c0cSopenharmony_ci        }
677e2e9c0cSopenharmony_ci    }
687e2e9c0cSopenharmony_ci}
697e2e9c0cSopenharmony_ci
707e2e9c0cSopenharmony_ciimpl DeserializeWith for i32 {
717e2e9c0cSopenharmony_ci    fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
727e2e9c0cSopenharmony_ci    where
737e2e9c0cSopenharmony_ci        D: Deserializer<'de>,
747e2e9c0cSopenharmony_ci    {
757e2e9c0cSopenharmony_ci        if Deserialize::deserialize(de)? {
767e2e9c0cSopenharmony_ci            Ok(123)
777e2e9c0cSopenharmony_ci        } else {
787e2e9c0cSopenharmony_ci            Ok(2)
797e2e9c0cSopenharmony_ci        }
807e2e9c0cSopenharmony_ci    }
817e2e9c0cSopenharmony_ci}
827e2e9c0cSopenharmony_ci
837e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
847e2e9c0cSopenharmony_cistruct DefaultStruct<A, B, C, D, E>
857e2e9c0cSopenharmony_ciwhere
867e2e9c0cSopenharmony_ci    C: MyDefault,
877e2e9c0cSopenharmony_ci    E: MyDefault,
887e2e9c0cSopenharmony_ci{
897e2e9c0cSopenharmony_ci    a1: A,
907e2e9c0cSopenharmony_ci    #[serde(default)]
917e2e9c0cSopenharmony_ci    a2: B,
927e2e9c0cSopenharmony_ci    #[serde(default = "MyDefault::my_default")]
937e2e9c0cSopenharmony_ci    a3: C,
947e2e9c0cSopenharmony_ci    #[serde(skip_deserializing)]
957e2e9c0cSopenharmony_ci    a4: D,
967e2e9c0cSopenharmony_ci    #[serde(skip_deserializing, default = "MyDefault::my_default")]
977e2e9c0cSopenharmony_ci    a5: E,
987e2e9c0cSopenharmony_ci}
997e2e9c0cSopenharmony_ci
1007e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
1017e2e9c0cSopenharmony_cistruct DefaultTupleStruct<A, B, C>(
1027e2e9c0cSopenharmony_ci    A,
1037e2e9c0cSopenharmony_ci    #[serde(default)] B,
1047e2e9c0cSopenharmony_ci    #[serde(default = "MyDefault::my_default")] C,
1057e2e9c0cSopenharmony_ci)
1067e2e9c0cSopenharmony_ciwhere
1077e2e9c0cSopenharmony_ci    C: MyDefault;
1087e2e9c0cSopenharmony_ci
1097e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
1107e2e9c0cSopenharmony_cistruct CollectOther {
1117e2e9c0cSopenharmony_ci    a: u32,
1127e2e9c0cSopenharmony_ci    b: u32,
1137e2e9c0cSopenharmony_ci    #[serde(flatten)]
1147e2e9c0cSopenharmony_ci    extra: HashMap<String, u32>,
1157e2e9c0cSopenharmony_ci}
1167e2e9c0cSopenharmony_ci
1177e2e9c0cSopenharmony_ci#[test]
1187e2e9c0cSopenharmony_cifn test_default_struct() {
1197e2e9c0cSopenharmony_ci    assert_de_tokens(
1207e2e9c0cSopenharmony_ci        &DefaultStruct {
1217e2e9c0cSopenharmony_ci            a1: 1,
1227e2e9c0cSopenharmony_ci            a2: 2,
1237e2e9c0cSopenharmony_ci            a3: 3,
1247e2e9c0cSopenharmony_ci            a4: 0,
1257e2e9c0cSopenharmony_ci            a5: 123,
1267e2e9c0cSopenharmony_ci        },
1277e2e9c0cSopenharmony_ci        &[
1287e2e9c0cSopenharmony_ci            Token::Struct {
1297e2e9c0cSopenharmony_ci                name: "DefaultStruct",
1307e2e9c0cSopenharmony_ci                len: 3,
1317e2e9c0cSopenharmony_ci            },
1327e2e9c0cSopenharmony_ci            Token::Str("a1"),
1337e2e9c0cSopenharmony_ci            Token::I32(1),
1347e2e9c0cSopenharmony_ci            Token::Str("a2"),
1357e2e9c0cSopenharmony_ci            Token::I32(2),
1367e2e9c0cSopenharmony_ci            Token::Str("a3"),
1377e2e9c0cSopenharmony_ci            Token::I32(3),
1387e2e9c0cSopenharmony_ci            Token::Str("a4"),
1397e2e9c0cSopenharmony_ci            Token::I32(4),
1407e2e9c0cSopenharmony_ci            Token::Str("a5"),
1417e2e9c0cSopenharmony_ci            Token::I32(5),
1427e2e9c0cSopenharmony_ci            Token::StructEnd,
1437e2e9c0cSopenharmony_ci        ],
1447e2e9c0cSopenharmony_ci    );
1457e2e9c0cSopenharmony_ci
1467e2e9c0cSopenharmony_ci    assert_de_tokens(
1477e2e9c0cSopenharmony_ci        &DefaultStruct {
1487e2e9c0cSopenharmony_ci            a1: 1,
1497e2e9c0cSopenharmony_ci            a2: 0,
1507e2e9c0cSopenharmony_ci            a3: 123,
1517e2e9c0cSopenharmony_ci            a4: 0,
1527e2e9c0cSopenharmony_ci            a5: 123,
1537e2e9c0cSopenharmony_ci        },
1547e2e9c0cSopenharmony_ci        &[
1557e2e9c0cSopenharmony_ci            Token::Struct {
1567e2e9c0cSopenharmony_ci                name: "DefaultStruct",
1577e2e9c0cSopenharmony_ci                len: 3,
1587e2e9c0cSopenharmony_ci            },
1597e2e9c0cSopenharmony_ci            Token::Str("a1"),
1607e2e9c0cSopenharmony_ci            Token::I32(1),
1617e2e9c0cSopenharmony_ci            Token::StructEnd,
1627e2e9c0cSopenharmony_ci        ],
1637e2e9c0cSopenharmony_ci    );
1647e2e9c0cSopenharmony_ci}
1657e2e9c0cSopenharmony_ci
1667e2e9c0cSopenharmony_ci#[test]
1677e2e9c0cSopenharmony_cifn test_default_tuple() {
1687e2e9c0cSopenharmony_ci    assert_de_tokens(
1697e2e9c0cSopenharmony_ci        &DefaultTupleStruct(1, 2, 3),
1707e2e9c0cSopenharmony_ci        &[
1717e2e9c0cSopenharmony_ci            Token::TupleStruct {
1727e2e9c0cSopenharmony_ci                name: "DefaultTupleStruct",
1737e2e9c0cSopenharmony_ci                len: 3,
1747e2e9c0cSopenharmony_ci            },
1757e2e9c0cSopenharmony_ci            Token::I32(1),
1767e2e9c0cSopenharmony_ci            Token::I32(2),
1777e2e9c0cSopenharmony_ci            Token::I32(3),
1787e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
1797e2e9c0cSopenharmony_ci        ],
1807e2e9c0cSopenharmony_ci    );
1817e2e9c0cSopenharmony_ci
1827e2e9c0cSopenharmony_ci    assert_de_tokens(
1837e2e9c0cSopenharmony_ci        &DefaultTupleStruct(1, 0, 123),
1847e2e9c0cSopenharmony_ci        &[
1857e2e9c0cSopenharmony_ci            Token::TupleStruct {
1867e2e9c0cSopenharmony_ci                name: "DefaultTupleStruct",
1877e2e9c0cSopenharmony_ci                len: 3,
1887e2e9c0cSopenharmony_ci            },
1897e2e9c0cSopenharmony_ci            Token::I32(1),
1907e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
1917e2e9c0cSopenharmony_ci        ],
1927e2e9c0cSopenharmony_ci    );
1937e2e9c0cSopenharmony_ci}
1947e2e9c0cSopenharmony_ci
1957e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
1967e2e9c0cSopenharmony_cienum DefaultStructVariant<A, B, C, D, E>
1977e2e9c0cSopenharmony_ciwhere
1987e2e9c0cSopenharmony_ci    C: MyDefault,
1997e2e9c0cSopenharmony_ci    E: MyDefault,
2007e2e9c0cSopenharmony_ci{
2017e2e9c0cSopenharmony_ci    Struct {
2027e2e9c0cSopenharmony_ci        a1: A,
2037e2e9c0cSopenharmony_ci        #[serde(default)]
2047e2e9c0cSopenharmony_ci        a2: B,
2057e2e9c0cSopenharmony_ci        #[serde(default = "MyDefault::my_default")]
2067e2e9c0cSopenharmony_ci        a3: C,
2077e2e9c0cSopenharmony_ci        #[serde(skip_deserializing)]
2087e2e9c0cSopenharmony_ci        a4: D,
2097e2e9c0cSopenharmony_ci        #[serde(skip_deserializing, default = "MyDefault::my_default")]
2107e2e9c0cSopenharmony_ci        a5: E,
2117e2e9c0cSopenharmony_ci    },
2127e2e9c0cSopenharmony_ci}
2137e2e9c0cSopenharmony_ci
2147e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
2157e2e9c0cSopenharmony_cienum DefaultTupleVariant<A, B, C>
2167e2e9c0cSopenharmony_ciwhere
2177e2e9c0cSopenharmony_ci    C: MyDefault,
2187e2e9c0cSopenharmony_ci{
2197e2e9c0cSopenharmony_ci    Tuple(
2207e2e9c0cSopenharmony_ci        A,
2217e2e9c0cSopenharmony_ci        #[serde(default)] B,
2227e2e9c0cSopenharmony_ci        #[serde(default = "MyDefault::my_default")] C,
2237e2e9c0cSopenharmony_ci    ),
2247e2e9c0cSopenharmony_ci}
2257e2e9c0cSopenharmony_ci
2267e2e9c0cSopenharmony_ci#[test]
2277e2e9c0cSopenharmony_cifn test_default_struct_variant() {
2287e2e9c0cSopenharmony_ci    assert_de_tokens(
2297e2e9c0cSopenharmony_ci        &DefaultStructVariant::Struct {
2307e2e9c0cSopenharmony_ci            a1: 1,
2317e2e9c0cSopenharmony_ci            a2: 2,
2327e2e9c0cSopenharmony_ci            a3: 3,
2337e2e9c0cSopenharmony_ci            a4: 0,
2347e2e9c0cSopenharmony_ci            a5: 123,
2357e2e9c0cSopenharmony_ci        },
2367e2e9c0cSopenharmony_ci        &[
2377e2e9c0cSopenharmony_ci            Token::StructVariant {
2387e2e9c0cSopenharmony_ci                name: "DefaultStructVariant",
2397e2e9c0cSopenharmony_ci                variant: "Struct",
2407e2e9c0cSopenharmony_ci                len: 3,
2417e2e9c0cSopenharmony_ci            },
2427e2e9c0cSopenharmony_ci            Token::Str("a1"),
2437e2e9c0cSopenharmony_ci            Token::I32(1),
2447e2e9c0cSopenharmony_ci            Token::Str("a2"),
2457e2e9c0cSopenharmony_ci            Token::I32(2),
2467e2e9c0cSopenharmony_ci            Token::Str("a3"),
2477e2e9c0cSopenharmony_ci            Token::I32(3),
2487e2e9c0cSopenharmony_ci            Token::Str("a4"),
2497e2e9c0cSopenharmony_ci            Token::I32(4),
2507e2e9c0cSopenharmony_ci            Token::Str("a5"),
2517e2e9c0cSopenharmony_ci            Token::I32(5),
2527e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
2537e2e9c0cSopenharmony_ci        ],
2547e2e9c0cSopenharmony_ci    );
2557e2e9c0cSopenharmony_ci
2567e2e9c0cSopenharmony_ci    assert_de_tokens(
2577e2e9c0cSopenharmony_ci        &DefaultStructVariant::Struct {
2587e2e9c0cSopenharmony_ci            a1: 1,
2597e2e9c0cSopenharmony_ci            a2: 0,
2607e2e9c0cSopenharmony_ci            a3: 123,
2617e2e9c0cSopenharmony_ci            a4: 0,
2627e2e9c0cSopenharmony_ci            a5: 123,
2637e2e9c0cSopenharmony_ci        },
2647e2e9c0cSopenharmony_ci        &[
2657e2e9c0cSopenharmony_ci            Token::StructVariant {
2667e2e9c0cSopenharmony_ci                name: "DefaultStructVariant",
2677e2e9c0cSopenharmony_ci                variant: "Struct",
2687e2e9c0cSopenharmony_ci                len: 3,
2697e2e9c0cSopenharmony_ci            },
2707e2e9c0cSopenharmony_ci            Token::Str("a1"),
2717e2e9c0cSopenharmony_ci            Token::I32(1),
2727e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
2737e2e9c0cSopenharmony_ci        ],
2747e2e9c0cSopenharmony_ci    );
2757e2e9c0cSopenharmony_ci}
2767e2e9c0cSopenharmony_ci
2777e2e9c0cSopenharmony_ci#[test]
2787e2e9c0cSopenharmony_cifn test_default_tuple_variant() {
2797e2e9c0cSopenharmony_ci    assert_de_tokens(
2807e2e9c0cSopenharmony_ci        &DefaultTupleVariant::Tuple(1, 2, 3),
2817e2e9c0cSopenharmony_ci        &[
2827e2e9c0cSopenharmony_ci            Token::TupleVariant {
2837e2e9c0cSopenharmony_ci                name: "DefaultTupleVariant",
2847e2e9c0cSopenharmony_ci                variant: "Tuple",
2857e2e9c0cSopenharmony_ci                len: 3,
2867e2e9c0cSopenharmony_ci            },
2877e2e9c0cSopenharmony_ci            Token::I32(1),
2887e2e9c0cSopenharmony_ci            Token::I32(2),
2897e2e9c0cSopenharmony_ci            Token::I32(3),
2907e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
2917e2e9c0cSopenharmony_ci        ],
2927e2e9c0cSopenharmony_ci    );
2937e2e9c0cSopenharmony_ci
2947e2e9c0cSopenharmony_ci    assert_de_tokens(
2957e2e9c0cSopenharmony_ci        &DefaultTupleVariant::Tuple(1, 0, 123),
2967e2e9c0cSopenharmony_ci        &[
2977e2e9c0cSopenharmony_ci            Token::TupleVariant {
2987e2e9c0cSopenharmony_ci                name: "DefaultTupleVariant",
2997e2e9c0cSopenharmony_ci                variant: "Tuple",
3007e2e9c0cSopenharmony_ci                len: 3,
3017e2e9c0cSopenharmony_ci            },
3027e2e9c0cSopenharmony_ci            Token::I32(1),
3037e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
3047e2e9c0cSopenharmony_ci        ],
3057e2e9c0cSopenharmony_ci    );
3067e2e9c0cSopenharmony_ci}
3077e2e9c0cSopenharmony_ci
3087e2e9c0cSopenharmony_ci// Does not implement std::default::Default.
3097e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
3107e2e9c0cSopenharmony_cistruct NoStdDefault(i8);
3117e2e9c0cSopenharmony_ci
3127e2e9c0cSopenharmony_ciimpl MyDefault for NoStdDefault {
3137e2e9c0cSopenharmony_ci    fn my_default() -> Self {
3147e2e9c0cSopenharmony_ci        NoStdDefault(123)
3157e2e9c0cSopenharmony_ci    }
3167e2e9c0cSopenharmony_ci}
3177e2e9c0cSopenharmony_ci
3187e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
3197e2e9c0cSopenharmony_cistruct ContainsNoStdDefault<A: MyDefault> {
3207e2e9c0cSopenharmony_ci    #[serde(default = "MyDefault::my_default")]
3217e2e9c0cSopenharmony_ci    a: A,
3227e2e9c0cSopenharmony_ci}
3237e2e9c0cSopenharmony_ci
3247e2e9c0cSopenharmony_ci// Tests that a struct field does not need to implement std::default::Default if
3257e2e9c0cSopenharmony_ci// it is annotated with `default=...`.
3267e2e9c0cSopenharmony_ci#[test]
3277e2e9c0cSopenharmony_cifn test_no_std_default() {
3287e2e9c0cSopenharmony_ci    assert_de_tokens(
3297e2e9c0cSopenharmony_ci        &ContainsNoStdDefault {
3307e2e9c0cSopenharmony_ci            a: NoStdDefault(123),
3317e2e9c0cSopenharmony_ci        },
3327e2e9c0cSopenharmony_ci        &[
3337e2e9c0cSopenharmony_ci            Token::Struct {
3347e2e9c0cSopenharmony_ci                name: "ContainsNoStdDefault",
3357e2e9c0cSopenharmony_ci                len: 1,
3367e2e9c0cSopenharmony_ci            },
3377e2e9c0cSopenharmony_ci            Token::StructEnd,
3387e2e9c0cSopenharmony_ci        ],
3397e2e9c0cSopenharmony_ci    );
3407e2e9c0cSopenharmony_ci
3417e2e9c0cSopenharmony_ci    assert_de_tokens(
3427e2e9c0cSopenharmony_ci        &ContainsNoStdDefault { a: NoStdDefault(8) },
3437e2e9c0cSopenharmony_ci        &[
3447e2e9c0cSopenharmony_ci            Token::Struct {
3457e2e9c0cSopenharmony_ci                name: "ContainsNoStdDefault",
3467e2e9c0cSopenharmony_ci                len: 1,
3477e2e9c0cSopenharmony_ci            },
3487e2e9c0cSopenharmony_ci            Token::Str("a"),
3497e2e9c0cSopenharmony_ci            Token::NewtypeStruct {
3507e2e9c0cSopenharmony_ci                name: "NoStdDefault",
3517e2e9c0cSopenharmony_ci            },
3527e2e9c0cSopenharmony_ci            Token::I8(8),
3537e2e9c0cSopenharmony_ci            Token::StructEnd,
3547e2e9c0cSopenharmony_ci        ],
3557e2e9c0cSopenharmony_ci    );
3567e2e9c0cSopenharmony_ci}
3577e2e9c0cSopenharmony_ci
3587e2e9c0cSopenharmony_ci// Does not implement Deserialize.
3597e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq)]
3607e2e9c0cSopenharmony_cistruct NotDeserializeStruct(i8);
3617e2e9c0cSopenharmony_ci
3627e2e9c0cSopenharmony_ciimpl Default for NotDeserializeStruct {
3637e2e9c0cSopenharmony_ci    fn default() -> Self {
3647e2e9c0cSopenharmony_ci        NotDeserializeStruct(123)
3657e2e9c0cSopenharmony_ci    }
3667e2e9c0cSopenharmony_ci}
3677e2e9c0cSopenharmony_ci
3687e2e9c0cSopenharmony_ciimpl DeserializeWith for NotDeserializeStruct {
3697e2e9c0cSopenharmony_ci    fn deserialize_with<'de, D>(_: D) -> Result<Self, D::Error>
3707e2e9c0cSopenharmony_ci    where
3717e2e9c0cSopenharmony_ci        D: Deserializer<'de>,
3727e2e9c0cSopenharmony_ci    {
3737e2e9c0cSopenharmony_ci        panic!()
3747e2e9c0cSopenharmony_ci    }
3757e2e9c0cSopenharmony_ci}
3767e2e9c0cSopenharmony_ci
3777e2e9c0cSopenharmony_ci// Does not implement Deserialize.
3787e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq)]
3797e2e9c0cSopenharmony_cienum NotDeserializeEnum {
3807e2e9c0cSopenharmony_ci    Trouble,
3817e2e9c0cSopenharmony_ci}
3827e2e9c0cSopenharmony_ci
3837e2e9c0cSopenharmony_ciimpl MyDefault for NotDeserializeEnum {
3847e2e9c0cSopenharmony_ci    fn my_default() -> Self {
3857e2e9c0cSopenharmony_ci        NotDeserializeEnum::Trouble
3867e2e9c0cSopenharmony_ci    }
3877e2e9c0cSopenharmony_ci}
3887e2e9c0cSopenharmony_ci
3897e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
3907e2e9c0cSopenharmony_cistruct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
3917e2e9c0cSopenharmony_ci    #[serde(skip_deserializing)]
3927e2e9c0cSopenharmony_ci    a: A,
3937e2e9c0cSopenharmony_ci    #[serde(skip_deserializing, default)]
3947e2e9c0cSopenharmony_ci    b: B,
3957e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
3967e2e9c0cSopenharmony_ci    c: C,
3977e2e9c0cSopenharmony_ci    #[serde(skip_deserializing, default = "MyDefault::my_default")]
3987e2e9c0cSopenharmony_ci    e: E,
3997e2e9c0cSopenharmony_ci}
4007e2e9c0cSopenharmony_ci
4017e2e9c0cSopenharmony_ci// Tests that a struct field does not need to implement Deserialize if it is
4027e2e9c0cSopenharmony_ci// annotated with skip_deserializing, whether using the std Default or a
4037e2e9c0cSopenharmony_ci// custom default.
4047e2e9c0cSopenharmony_ci#[test]
4057e2e9c0cSopenharmony_cifn test_elt_not_deserialize() {
4067e2e9c0cSopenharmony_ci    assert_de_tokens(
4077e2e9c0cSopenharmony_ci        &ContainsNotDeserialize {
4087e2e9c0cSopenharmony_ci            a: NotDeserializeStruct(123),
4097e2e9c0cSopenharmony_ci            b: NotDeserializeStruct(123),
4107e2e9c0cSopenharmony_ci            c: NotDeserializeStruct(123),
4117e2e9c0cSopenharmony_ci            e: NotDeserializeEnum::Trouble,
4127e2e9c0cSopenharmony_ci        },
4137e2e9c0cSopenharmony_ci        &[
4147e2e9c0cSopenharmony_ci            Token::Struct {
4157e2e9c0cSopenharmony_ci                name: "ContainsNotDeserialize",
4167e2e9c0cSopenharmony_ci                len: 1,
4177e2e9c0cSopenharmony_ci            },
4187e2e9c0cSopenharmony_ci            Token::StructEnd,
4197e2e9c0cSopenharmony_ci        ],
4207e2e9c0cSopenharmony_ci    );
4217e2e9c0cSopenharmony_ci}
4227e2e9c0cSopenharmony_ci
4237e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
4247e2e9c0cSopenharmony_ci#[serde(deny_unknown_fields)]
4257e2e9c0cSopenharmony_cistruct DenyUnknown {
4267e2e9c0cSopenharmony_ci    a1: i32,
4277e2e9c0cSopenharmony_ci}
4287e2e9c0cSopenharmony_ci
4297e2e9c0cSopenharmony_ci#[test]
4307e2e9c0cSopenharmony_cifn test_ignore_unknown() {
4317e2e9c0cSopenharmony_ci    // 'Default' allows unknown. Basic smoke test of ignore...
4327e2e9c0cSopenharmony_ci    assert_de_tokens(
4337e2e9c0cSopenharmony_ci        &DefaultStruct {
4347e2e9c0cSopenharmony_ci            a1: 1,
4357e2e9c0cSopenharmony_ci            a2: 2,
4367e2e9c0cSopenharmony_ci            a3: 3,
4377e2e9c0cSopenharmony_ci            a4: 0,
4387e2e9c0cSopenharmony_ci            a5: 123,
4397e2e9c0cSopenharmony_ci        },
4407e2e9c0cSopenharmony_ci        &[
4417e2e9c0cSopenharmony_ci            Token::Struct {
4427e2e9c0cSopenharmony_ci                name: "DefaultStruct",
4437e2e9c0cSopenharmony_ci                len: 3,
4447e2e9c0cSopenharmony_ci            },
4457e2e9c0cSopenharmony_ci            Token::Str("whoops1"),
4467e2e9c0cSopenharmony_ci            Token::I32(2),
4477e2e9c0cSopenharmony_ci            Token::Str("a1"),
4487e2e9c0cSopenharmony_ci            Token::I32(1),
4497e2e9c0cSopenharmony_ci            Token::Str("whoops2"),
4507e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
4517e2e9c0cSopenharmony_ci            Token::I32(2),
4527e2e9c0cSopenharmony_ci            Token::SeqEnd,
4537e2e9c0cSopenharmony_ci            Token::Str("a2"),
4547e2e9c0cSopenharmony_ci            Token::I32(2),
4557e2e9c0cSopenharmony_ci            Token::Str("whoops3"),
4567e2e9c0cSopenharmony_ci            Token::I32(2),
4577e2e9c0cSopenharmony_ci            Token::Str("a3"),
4587e2e9c0cSopenharmony_ci            Token::I32(3),
4597e2e9c0cSopenharmony_ci            Token::StructEnd,
4607e2e9c0cSopenharmony_ci        ],
4617e2e9c0cSopenharmony_ci    );
4627e2e9c0cSopenharmony_ci
4637e2e9c0cSopenharmony_ci    assert_de_tokens_error::<DenyUnknown>(
4647e2e9c0cSopenharmony_ci        &[
4657e2e9c0cSopenharmony_ci            Token::Struct {
4667e2e9c0cSopenharmony_ci                name: "DenyUnknown",
4677e2e9c0cSopenharmony_ci                len: 1,
4687e2e9c0cSopenharmony_ci            },
4697e2e9c0cSopenharmony_ci            Token::Str("a1"),
4707e2e9c0cSopenharmony_ci            Token::I32(1),
4717e2e9c0cSopenharmony_ci            Token::Str("whoops"),
4727e2e9c0cSopenharmony_ci        ],
4737e2e9c0cSopenharmony_ci        "unknown field `whoops`, expected `a1`",
4747e2e9c0cSopenharmony_ci    );
4757e2e9c0cSopenharmony_ci}
4767e2e9c0cSopenharmony_ci
4777e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
4787e2e9c0cSopenharmony_ci#[serde(rename = "Superhero")]
4797e2e9c0cSopenharmony_cistruct RenameStruct {
4807e2e9c0cSopenharmony_ci    a1: i32,
4817e2e9c0cSopenharmony_ci    #[serde(rename = "a3")]
4827e2e9c0cSopenharmony_ci    a2: i32,
4837e2e9c0cSopenharmony_ci}
4847e2e9c0cSopenharmony_ci
4857e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
4867e2e9c0cSopenharmony_ci#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
4877e2e9c0cSopenharmony_cistruct RenameStructSerializeDeserialize {
4887e2e9c0cSopenharmony_ci    a1: i32,
4897e2e9c0cSopenharmony_ci    #[serde(rename(serialize = "a4", deserialize = "a5"))]
4907e2e9c0cSopenharmony_ci    a2: i32,
4917e2e9c0cSopenharmony_ci}
4927e2e9c0cSopenharmony_ci
4937e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
4947e2e9c0cSopenharmony_ci#[serde(deny_unknown_fields)]
4957e2e9c0cSopenharmony_cistruct AliasStruct {
4967e2e9c0cSopenharmony_ci    a1: i32,
4977e2e9c0cSopenharmony_ci    #[serde(alias = "a3")]
4987e2e9c0cSopenharmony_ci    a2: i32,
4997e2e9c0cSopenharmony_ci    #[serde(alias = "a5", rename = "a6")]
5007e2e9c0cSopenharmony_ci    a4: i32,
5017e2e9c0cSopenharmony_ci}
5027e2e9c0cSopenharmony_ci
5037e2e9c0cSopenharmony_ci#[test]
5047e2e9c0cSopenharmony_cifn test_rename_struct() {
5057e2e9c0cSopenharmony_ci    assert_tokens(
5067e2e9c0cSopenharmony_ci        &RenameStruct { a1: 1, a2: 2 },
5077e2e9c0cSopenharmony_ci        &[
5087e2e9c0cSopenharmony_ci            Token::Struct {
5097e2e9c0cSopenharmony_ci                name: "Superhero",
5107e2e9c0cSopenharmony_ci                len: 2,
5117e2e9c0cSopenharmony_ci            },
5127e2e9c0cSopenharmony_ci            Token::Str("a1"),
5137e2e9c0cSopenharmony_ci            Token::I32(1),
5147e2e9c0cSopenharmony_ci            Token::Str("a3"),
5157e2e9c0cSopenharmony_ci            Token::I32(2),
5167e2e9c0cSopenharmony_ci            Token::StructEnd,
5177e2e9c0cSopenharmony_ci        ],
5187e2e9c0cSopenharmony_ci    );
5197e2e9c0cSopenharmony_ci
5207e2e9c0cSopenharmony_ci    assert_ser_tokens(
5217e2e9c0cSopenharmony_ci        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
5227e2e9c0cSopenharmony_ci        &[
5237e2e9c0cSopenharmony_ci            Token::Struct {
5247e2e9c0cSopenharmony_ci                name: "SuperheroSer",
5257e2e9c0cSopenharmony_ci                len: 2,
5267e2e9c0cSopenharmony_ci            },
5277e2e9c0cSopenharmony_ci            Token::Str("a1"),
5287e2e9c0cSopenharmony_ci            Token::I32(1),
5297e2e9c0cSopenharmony_ci            Token::Str("a4"),
5307e2e9c0cSopenharmony_ci            Token::I32(2),
5317e2e9c0cSopenharmony_ci            Token::StructEnd,
5327e2e9c0cSopenharmony_ci        ],
5337e2e9c0cSopenharmony_ci    );
5347e2e9c0cSopenharmony_ci
5357e2e9c0cSopenharmony_ci    assert_de_tokens(
5367e2e9c0cSopenharmony_ci        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
5377e2e9c0cSopenharmony_ci        &[
5387e2e9c0cSopenharmony_ci            Token::Struct {
5397e2e9c0cSopenharmony_ci                name: "SuperheroDe",
5407e2e9c0cSopenharmony_ci                len: 2,
5417e2e9c0cSopenharmony_ci            },
5427e2e9c0cSopenharmony_ci            Token::Str("a1"),
5437e2e9c0cSopenharmony_ci            Token::I32(1),
5447e2e9c0cSopenharmony_ci            Token::Str("a5"),
5457e2e9c0cSopenharmony_ci            Token::I32(2),
5467e2e9c0cSopenharmony_ci            Token::StructEnd,
5477e2e9c0cSopenharmony_ci        ],
5487e2e9c0cSopenharmony_ci    );
5497e2e9c0cSopenharmony_ci
5507e2e9c0cSopenharmony_ci    assert_de_tokens(
5517e2e9c0cSopenharmony_ci        &AliasStruct {
5527e2e9c0cSopenharmony_ci            a1: 1,
5537e2e9c0cSopenharmony_ci            a2: 2,
5547e2e9c0cSopenharmony_ci            a4: 3,
5557e2e9c0cSopenharmony_ci        },
5567e2e9c0cSopenharmony_ci        &[
5577e2e9c0cSopenharmony_ci            Token::Struct {
5587e2e9c0cSopenharmony_ci                name: "AliasStruct",
5597e2e9c0cSopenharmony_ci                len: 3,
5607e2e9c0cSopenharmony_ci            },
5617e2e9c0cSopenharmony_ci            Token::Str("a1"),
5627e2e9c0cSopenharmony_ci            Token::I32(1),
5637e2e9c0cSopenharmony_ci            Token::Str("a2"),
5647e2e9c0cSopenharmony_ci            Token::I32(2),
5657e2e9c0cSopenharmony_ci            Token::Str("a5"),
5667e2e9c0cSopenharmony_ci            Token::I32(3),
5677e2e9c0cSopenharmony_ci            Token::StructEnd,
5687e2e9c0cSopenharmony_ci        ],
5697e2e9c0cSopenharmony_ci    );
5707e2e9c0cSopenharmony_ci
5717e2e9c0cSopenharmony_ci    assert_de_tokens(
5727e2e9c0cSopenharmony_ci        &AliasStruct {
5737e2e9c0cSopenharmony_ci            a1: 1,
5747e2e9c0cSopenharmony_ci            a2: 2,
5757e2e9c0cSopenharmony_ci            a4: 3,
5767e2e9c0cSopenharmony_ci        },
5777e2e9c0cSopenharmony_ci        &[
5787e2e9c0cSopenharmony_ci            Token::Struct {
5797e2e9c0cSopenharmony_ci                name: "AliasStruct",
5807e2e9c0cSopenharmony_ci                len: 3,
5817e2e9c0cSopenharmony_ci            },
5827e2e9c0cSopenharmony_ci            Token::Str("a1"),
5837e2e9c0cSopenharmony_ci            Token::I32(1),
5847e2e9c0cSopenharmony_ci            Token::Str("a3"),
5857e2e9c0cSopenharmony_ci            Token::I32(2),
5867e2e9c0cSopenharmony_ci            Token::Str("a6"),
5877e2e9c0cSopenharmony_ci            Token::I32(3),
5887e2e9c0cSopenharmony_ci            Token::StructEnd,
5897e2e9c0cSopenharmony_ci        ],
5907e2e9c0cSopenharmony_ci    );
5917e2e9c0cSopenharmony_ci}
5927e2e9c0cSopenharmony_ci
5937e2e9c0cSopenharmony_ci#[test]
5947e2e9c0cSopenharmony_cifn test_unknown_field_rename_struct() {
5957e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AliasStruct>(
5967e2e9c0cSopenharmony_ci        &[
5977e2e9c0cSopenharmony_ci            Token::Struct {
5987e2e9c0cSopenharmony_ci                name: "AliasStruct",
5997e2e9c0cSopenharmony_ci                len: 3,
6007e2e9c0cSopenharmony_ci            },
6017e2e9c0cSopenharmony_ci            Token::Str("a1"),
6027e2e9c0cSopenharmony_ci            Token::I32(1),
6037e2e9c0cSopenharmony_ci            Token::Str("a3"),
6047e2e9c0cSopenharmony_ci            Token::I32(2),
6057e2e9c0cSopenharmony_ci            Token::Str("a4"),
6067e2e9c0cSopenharmony_ci            Token::I32(3),
6077e2e9c0cSopenharmony_ci        ],
6087e2e9c0cSopenharmony_ci        "unknown field `a4`, expected one of `a1`, `a2`, `a3`, `a5`, `a6`",
6097e2e9c0cSopenharmony_ci    );
6107e2e9c0cSopenharmony_ci}
6117e2e9c0cSopenharmony_ci
6127e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
6137e2e9c0cSopenharmony_ci#[serde(rename = "Superhero")]
6147e2e9c0cSopenharmony_cienum RenameEnum {
6157e2e9c0cSopenharmony_ci    #[serde(rename = "bruce_wayne")]
6167e2e9c0cSopenharmony_ci    Batman,
6177e2e9c0cSopenharmony_ci    #[serde(rename = "clark_kent")]
6187e2e9c0cSopenharmony_ci    Superman(i8),
6197e2e9c0cSopenharmony_ci    #[serde(rename = "diana_prince")]
6207e2e9c0cSopenharmony_ci    WonderWoman(i8, i8),
6217e2e9c0cSopenharmony_ci    #[serde(rename = "barry_allan")]
6227e2e9c0cSopenharmony_ci    Flash {
6237e2e9c0cSopenharmony_ci        #[serde(rename = "b")]
6247e2e9c0cSopenharmony_ci        a: i32,
6257e2e9c0cSopenharmony_ci    },
6267e2e9c0cSopenharmony_ci}
6277e2e9c0cSopenharmony_ci
6287e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize, Serialize)]
6297e2e9c0cSopenharmony_ci#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
6307e2e9c0cSopenharmony_cienum RenameEnumSerializeDeserialize<A> {
6317e2e9c0cSopenharmony_ci    #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
6327e2e9c0cSopenharmony_ci    Robin {
6337e2e9c0cSopenharmony_ci        a: i8,
6347e2e9c0cSopenharmony_ci        #[serde(rename(serialize = "c"))]
6357e2e9c0cSopenharmony_ci        #[serde(rename(deserialize = "d"))]
6367e2e9c0cSopenharmony_ci        b: A,
6377e2e9c0cSopenharmony_ci    },
6387e2e9c0cSopenharmony_ci}
6397e2e9c0cSopenharmony_ci
6407e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
6417e2e9c0cSopenharmony_ci#[serde(deny_unknown_fields)]
6427e2e9c0cSopenharmony_cienum AliasEnum {
6437e2e9c0cSopenharmony_ci    #[serde(rename = "sailor_moon", alias = "usagi_tsukino")]
6447e2e9c0cSopenharmony_ci    SailorMoon {
6457e2e9c0cSopenharmony_ci        a: i8,
6467e2e9c0cSopenharmony_ci        #[serde(alias = "c")]
6477e2e9c0cSopenharmony_ci        b: i8,
6487e2e9c0cSopenharmony_ci        #[serde(alias = "e", rename = "f")]
6497e2e9c0cSopenharmony_ci        d: i8,
6507e2e9c0cSopenharmony_ci    },
6517e2e9c0cSopenharmony_ci}
6527e2e9c0cSopenharmony_ci
6537e2e9c0cSopenharmony_ci#[test]
6547e2e9c0cSopenharmony_cifn test_rename_enum() {
6557e2e9c0cSopenharmony_ci    assert_tokens(
6567e2e9c0cSopenharmony_ci        &RenameEnum::Batman,
6577e2e9c0cSopenharmony_ci        &[Token::UnitVariant {
6587e2e9c0cSopenharmony_ci            name: "Superhero",
6597e2e9c0cSopenharmony_ci            variant: "bruce_wayne",
6607e2e9c0cSopenharmony_ci        }],
6617e2e9c0cSopenharmony_ci    );
6627e2e9c0cSopenharmony_ci
6637e2e9c0cSopenharmony_ci    assert_tokens(
6647e2e9c0cSopenharmony_ci        &RenameEnum::Superman(0),
6657e2e9c0cSopenharmony_ci        &[
6667e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
6677e2e9c0cSopenharmony_ci                name: "Superhero",
6687e2e9c0cSopenharmony_ci                variant: "clark_kent",
6697e2e9c0cSopenharmony_ci            },
6707e2e9c0cSopenharmony_ci            Token::I8(0),
6717e2e9c0cSopenharmony_ci        ],
6727e2e9c0cSopenharmony_ci    );
6737e2e9c0cSopenharmony_ci
6747e2e9c0cSopenharmony_ci    assert_tokens(
6757e2e9c0cSopenharmony_ci        &RenameEnum::WonderWoman(0, 1),
6767e2e9c0cSopenharmony_ci        &[
6777e2e9c0cSopenharmony_ci            Token::TupleVariant {
6787e2e9c0cSopenharmony_ci                name: "Superhero",
6797e2e9c0cSopenharmony_ci                variant: "diana_prince",
6807e2e9c0cSopenharmony_ci                len: 2,
6817e2e9c0cSopenharmony_ci            },
6827e2e9c0cSopenharmony_ci            Token::I8(0),
6837e2e9c0cSopenharmony_ci            Token::I8(1),
6847e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
6857e2e9c0cSopenharmony_ci        ],
6867e2e9c0cSopenharmony_ci    );
6877e2e9c0cSopenharmony_ci
6887e2e9c0cSopenharmony_ci    assert_tokens(
6897e2e9c0cSopenharmony_ci        &RenameEnum::Flash { a: 1 },
6907e2e9c0cSopenharmony_ci        &[
6917e2e9c0cSopenharmony_ci            Token::StructVariant {
6927e2e9c0cSopenharmony_ci                name: "Superhero",
6937e2e9c0cSopenharmony_ci                variant: "barry_allan",
6947e2e9c0cSopenharmony_ci                len: 1,
6957e2e9c0cSopenharmony_ci            },
6967e2e9c0cSopenharmony_ci            Token::Str("b"),
6977e2e9c0cSopenharmony_ci            Token::I32(1),
6987e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
6997e2e9c0cSopenharmony_ci        ],
7007e2e9c0cSopenharmony_ci    );
7017e2e9c0cSopenharmony_ci
7027e2e9c0cSopenharmony_ci    assert_ser_tokens(
7037e2e9c0cSopenharmony_ci        &RenameEnumSerializeDeserialize::Robin {
7047e2e9c0cSopenharmony_ci            a: 0,
7057e2e9c0cSopenharmony_ci            b: String::new(),
7067e2e9c0cSopenharmony_ci        },
7077e2e9c0cSopenharmony_ci        &[
7087e2e9c0cSopenharmony_ci            Token::StructVariant {
7097e2e9c0cSopenharmony_ci                name: "SuperheroSer",
7107e2e9c0cSopenharmony_ci                variant: "dick_grayson",
7117e2e9c0cSopenharmony_ci                len: 2,
7127e2e9c0cSopenharmony_ci            },
7137e2e9c0cSopenharmony_ci            Token::Str("a"),
7147e2e9c0cSopenharmony_ci            Token::I8(0),
7157e2e9c0cSopenharmony_ci            Token::Str("c"),
7167e2e9c0cSopenharmony_ci            Token::Str(""),
7177e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
7187e2e9c0cSopenharmony_ci        ],
7197e2e9c0cSopenharmony_ci    );
7207e2e9c0cSopenharmony_ci
7217e2e9c0cSopenharmony_ci    assert_de_tokens(
7227e2e9c0cSopenharmony_ci        &RenameEnumSerializeDeserialize::Robin {
7237e2e9c0cSopenharmony_ci            a: 0,
7247e2e9c0cSopenharmony_ci            b: String::new(),
7257e2e9c0cSopenharmony_ci        },
7267e2e9c0cSopenharmony_ci        &[
7277e2e9c0cSopenharmony_ci            Token::StructVariant {
7287e2e9c0cSopenharmony_ci                name: "SuperheroDe",
7297e2e9c0cSopenharmony_ci                variant: "jason_todd",
7307e2e9c0cSopenharmony_ci                len: 2,
7317e2e9c0cSopenharmony_ci            },
7327e2e9c0cSopenharmony_ci            Token::Str("a"),
7337e2e9c0cSopenharmony_ci            Token::I8(0),
7347e2e9c0cSopenharmony_ci            Token::Str("d"),
7357e2e9c0cSopenharmony_ci            Token::Str(""),
7367e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
7377e2e9c0cSopenharmony_ci        ],
7387e2e9c0cSopenharmony_ci    );
7397e2e9c0cSopenharmony_ci
7407e2e9c0cSopenharmony_ci    assert_de_tokens(
7417e2e9c0cSopenharmony_ci        &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
7427e2e9c0cSopenharmony_ci        &[
7437e2e9c0cSopenharmony_ci            Token::StructVariant {
7447e2e9c0cSopenharmony_ci                name: "AliasEnum",
7457e2e9c0cSopenharmony_ci                variant: "sailor_moon",
7467e2e9c0cSopenharmony_ci                len: 5,
7477e2e9c0cSopenharmony_ci            },
7487e2e9c0cSopenharmony_ci            Token::Str("a"),
7497e2e9c0cSopenharmony_ci            Token::I8(0),
7507e2e9c0cSopenharmony_ci            Token::Str("b"),
7517e2e9c0cSopenharmony_ci            Token::I8(1),
7527e2e9c0cSopenharmony_ci            Token::Str("e"),
7537e2e9c0cSopenharmony_ci            Token::I8(2),
7547e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
7557e2e9c0cSopenharmony_ci        ],
7567e2e9c0cSopenharmony_ci    );
7577e2e9c0cSopenharmony_ci
7587e2e9c0cSopenharmony_ci    assert_de_tokens(
7597e2e9c0cSopenharmony_ci        &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
7607e2e9c0cSopenharmony_ci        &[
7617e2e9c0cSopenharmony_ci            Token::StructVariant {
7627e2e9c0cSopenharmony_ci                name: "AliasEnum",
7637e2e9c0cSopenharmony_ci                variant: "usagi_tsukino",
7647e2e9c0cSopenharmony_ci                len: 5,
7657e2e9c0cSopenharmony_ci            },
7667e2e9c0cSopenharmony_ci            Token::Str("a"),
7677e2e9c0cSopenharmony_ci            Token::I8(0),
7687e2e9c0cSopenharmony_ci            Token::Str("c"),
7697e2e9c0cSopenharmony_ci            Token::I8(1),
7707e2e9c0cSopenharmony_ci            Token::Str("f"),
7717e2e9c0cSopenharmony_ci            Token::I8(2),
7727e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
7737e2e9c0cSopenharmony_ci        ],
7747e2e9c0cSopenharmony_ci    );
7757e2e9c0cSopenharmony_ci}
7767e2e9c0cSopenharmony_ci
7777e2e9c0cSopenharmony_ci#[test]
7787e2e9c0cSopenharmony_cifn test_unknown_field_rename_enum() {
7797e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AliasEnum>(
7807e2e9c0cSopenharmony_ci        &[Token::StructVariant {
7817e2e9c0cSopenharmony_ci            name: "AliasEnum",
7827e2e9c0cSopenharmony_ci            variant: "SailorMoon",
7837e2e9c0cSopenharmony_ci            len: 3,
7847e2e9c0cSopenharmony_ci        }],
7857e2e9c0cSopenharmony_ci        "unknown variant `SailorMoon`, expected `sailor_moon`",
7867e2e9c0cSopenharmony_ci    );
7877e2e9c0cSopenharmony_ci
7887e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AliasEnum>(
7897e2e9c0cSopenharmony_ci        &[
7907e2e9c0cSopenharmony_ci            Token::StructVariant {
7917e2e9c0cSopenharmony_ci                name: "AliasEnum",
7927e2e9c0cSopenharmony_ci                variant: "usagi_tsukino",
7937e2e9c0cSopenharmony_ci                len: 5,
7947e2e9c0cSopenharmony_ci            },
7957e2e9c0cSopenharmony_ci            Token::Str("a"),
7967e2e9c0cSopenharmony_ci            Token::I8(0),
7977e2e9c0cSopenharmony_ci            Token::Str("c"),
7987e2e9c0cSopenharmony_ci            Token::I8(1),
7997e2e9c0cSopenharmony_ci            Token::Str("d"),
8007e2e9c0cSopenharmony_ci            Token::I8(2),
8017e2e9c0cSopenharmony_ci        ],
8027e2e9c0cSopenharmony_ci        "unknown field `d`, expected one of `a`, `b`, `c`, `e`, `f`",
8037e2e9c0cSopenharmony_ci    );
8047e2e9c0cSopenharmony_ci}
8057e2e9c0cSopenharmony_ci
8067e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
8077e2e9c0cSopenharmony_cistruct SkipSerializingStruct<'a, B, C>
8087e2e9c0cSopenharmony_ciwhere
8097e2e9c0cSopenharmony_ci    C: ShouldSkip,
8107e2e9c0cSopenharmony_ci{
8117e2e9c0cSopenharmony_ci    a: &'a i8,
8127e2e9c0cSopenharmony_ci    #[serde(skip_serializing)]
8137e2e9c0cSopenharmony_ci    b: B,
8147e2e9c0cSopenharmony_ci    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
8157e2e9c0cSopenharmony_ci    c: C,
8167e2e9c0cSopenharmony_ci}
8177e2e9c0cSopenharmony_ci
8187e2e9c0cSopenharmony_ci#[test]
8197e2e9c0cSopenharmony_cifn test_skip_serializing_struct() {
8207e2e9c0cSopenharmony_ci    let a = 1;
8217e2e9c0cSopenharmony_ci    assert_ser_tokens(
8227e2e9c0cSopenharmony_ci        &SkipSerializingStruct { a: &a, b: 2, c: 3 },
8237e2e9c0cSopenharmony_ci        &[
8247e2e9c0cSopenharmony_ci            Token::Struct {
8257e2e9c0cSopenharmony_ci                name: "SkipSerializingStruct",
8267e2e9c0cSopenharmony_ci                len: 2,
8277e2e9c0cSopenharmony_ci            },
8287e2e9c0cSopenharmony_ci            Token::Str("a"),
8297e2e9c0cSopenharmony_ci            Token::I8(1),
8307e2e9c0cSopenharmony_ci            Token::Str("c"),
8317e2e9c0cSopenharmony_ci            Token::I32(3),
8327e2e9c0cSopenharmony_ci            Token::StructEnd,
8337e2e9c0cSopenharmony_ci        ],
8347e2e9c0cSopenharmony_ci    );
8357e2e9c0cSopenharmony_ci
8367e2e9c0cSopenharmony_ci    assert_ser_tokens(
8377e2e9c0cSopenharmony_ci        &SkipSerializingStruct {
8387e2e9c0cSopenharmony_ci            a: &a,
8397e2e9c0cSopenharmony_ci            b: 2,
8407e2e9c0cSopenharmony_ci            c: 123,
8417e2e9c0cSopenharmony_ci        },
8427e2e9c0cSopenharmony_ci        &[
8437e2e9c0cSopenharmony_ci            Token::Struct {
8447e2e9c0cSopenharmony_ci                name: "SkipSerializingStruct",
8457e2e9c0cSopenharmony_ci                len: 1,
8467e2e9c0cSopenharmony_ci            },
8477e2e9c0cSopenharmony_ci            Token::Str("a"),
8487e2e9c0cSopenharmony_ci            Token::I8(1),
8497e2e9c0cSopenharmony_ci            Token::StructEnd,
8507e2e9c0cSopenharmony_ci        ],
8517e2e9c0cSopenharmony_ci    );
8527e2e9c0cSopenharmony_ci}
8537e2e9c0cSopenharmony_ci
8547e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
8557e2e9c0cSopenharmony_cistruct SkipSerializingTupleStruct<'a, B, C>(
8567e2e9c0cSopenharmony_ci    &'a i8,
8577e2e9c0cSopenharmony_ci    #[serde(skip_serializing)] B,
8587e2e9c0cSopenharmony_ci    #[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
8597e2e9c0cSopenharmony_ci)
8607e2e9c0cSopenharmony_ciwhere
8617e2e9c0cSopenharmony_ci    C: ShouldSkip;
8627e2e9c0cSopenharmony_ci
8637e2e9c0cSopenharmony_ci#[test]
8647e2e9c0cSopenharmony_cifn test_skip_serializing_tuple_struct() {
8657e2e9c0cSopenharmony_ci    let a = 1;
8667e2e9c0cSopenharmony_ci    assert_ser_tokens(
8677e2e9c0cSopenharmony_ci        &SkipSerializingTupleStruct(&a, 2, 3),
8687e2e9c0cSopenharmony_ci        &[
8697e2e9c0cSopenharmony_ci            Token::TupleStruct {
8707e2e9c0cSopenharmony_ci                name: "SkipSerializingTupleStruct",
8717e2e9c0cSopenharmony_ci                len: 2,
8727e2e9c0cSopenharmony_ci            },
8737e2e9c0cSopenharmony_ci            Token::I8(1),
8747e2e9c0cSopenharmony_ci            Token::I32(3),
8757e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
8767e2e9c0cSopenharmony_ci        ],
8777e2e9c0cSopenharmony_ci    );
8787e2e9c0cSopenharmony_ci
8797e2e9c0cSopenharmony_ci    assert_ser_tokens(
8807e2e9c0cSopenharmony_ci        &SkipSerializingTupleStruct(&a, 2, 123),
8817e2e9c0cSopenharmony_ci        &[
8827e2e9c0cSopenharmony_ci            Token::TupleStruct {
8837e2e9c0cSopenharmony_ci                name: "SkipSerializingTupleStruct",
8847e2e9c0cSopenharmony_ci                len: 1,
8857e2e9c0cSopenharmony_ci            },
8867e2e9c0cSopenharmony_ci            Token::I8(1),
8877e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
8887e2e9c0cSopenharmony_ci        ],
8897e2e9c0cSopenharmony_ci    );
8907e2e9c0cSopenharmony_ci}
8917e2e9c0cSopenharmony_ci
8927e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
8937e2e9c0cSopenharmony_cistruct SkipStruct<B> {
8947e2e9c0cSopenharmony_ci    a: i8,
8957e2e9c0cSopenharmony_ci    #[serde(skip)]
8967e2e9c0cSopenharmony_ci    b: B,
8977e2e9c0cSopenharmony_ci}
8987e2e9c0cSopenharmony_ci
8997e2e9c0cSopenharmony_ci#[test]
9007e2e9c0cSopenharmony_cifn test_skip_struct() {
9017e2e9c0cSopenharmony_ci    assert_ser_tokens(
9027e2e9c0cSopenharmony_ci        &SkipStruct { a: 1, b: 2 },
9037e2e9c0cSopenharmony_ci        &[
9047e2e9c0cSopenharmony_ci            Token::Struct {
9057e2e9c0cSopenharmony_ci                name: "SkipStruct",
9067e2e9c0cSopenharmony_ci                len: 1,
9077e2e9c0cSopenharmony_ci            },
9087e2e9c0cSopenharmony_ci            Token::Str("a"),
9097e2e9c0cSopenharmony_ci            Token::I8(1),
9107e2e9c0cSopenharmony_ci            Token::StructEnd,
9117e2e9c0cSopenharmony_ci        ],
9127e2e9c0cSopenharmony_ci    );
9137e2e9c0cSopenharmony_ci
9147e2e9c0cSopenharmony_ci    assert_de_tokens(
9157e2e9c0cSopenharmony_ci        &SkipStruct { a: 1, b: 0 },
9167e2e9c0cSopenharmony_ci        &[
9177e2e9c0cSopenharmony_ci            Token::Struct {
9187e2e9c0cSopenharmony_ci                name: "SkipStruct",
9197e2e9c0cSopenharmony_ci                len: 1,
9207e2e9c0cSopenharmony_ci            },
9217e2e9c0cSopenharmony_ci            Token::Str("a"),
9227e2e9c0cSopenharmony_ci            Token::I8(1),
9237e2e9c0cSopenharmony_ci            Token::StructEnd,
9247e2e9c0cSopenharmony_ci        ],
9257e2e9c0cSopenharmony_ci    );
9267e2e9c0cSopenharmony_ci}
9277e2e9c0cSopenharmony_ci
9287e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
9297e2e9c0cSopenharmony_cienum SkipSerializingEnum<'a, B, C>
9307e2e9c0cSopenharmony_ciwhere
9317e2e9c0cSopenharmony_ci    C: ShouldSkip,
9327e2e9c0cSopenharmony_ci{
9337e2e9c0cSopenharmony_ci    Struct {
9347e2e9c0cSopenharmony_ci        a: &'a i8,
9357e2e9c0cSopenharmony_ci        #[serde(skip_serializing)]
9367e2e9c0cSopenharmony_ci        _b: B,
9377e2e9c0cSopenharmony_ci        #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
9387e2e9c0cSopenharmony_ci        c: C,
9397e2e9c0cSopenharmony_ci    },
9407e2e9c0cSopenharmony_ci    Tuple(
9417e2e9c0cSopenharmony_ci        &'a i8,
9427e2e9c0cSopenharmony_ci        #[serde(skip_serializing)] B,
9437e2e9c0cSopenharmony_ci        #[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
9447e2e9c0cSopenharmony_ci    ),
9457e2e9c0cSopenharmony_ci}
9467e2e9c0cSopenharmony_ci
9477e2e9c0cSopenharmony_ci#[test]
9487e2e9c0cSopenharmony_cifn test_skip_serializing_enum() {
9497e2e9c0cSopenharmony_ci    let a = 1;
9507e2e9c0cSopenharmony_ci    assert_ser_tokens(
9517e2e9c0cSopenharmony_ci        &SkipSerializingEnum::Struct { a: &a, _b: 2, c: 3 },
9527e2e9c0cSopenharmony_ci        &[
9537e2e9c0cSopenharmony_ci            Token::StructVariant {
9547e2e9c0cSopenharmony_ci                name: "SkipSerializingEnum",
9557e2e9c0cSopenharmony_ci                variant: "Struct",
9567e2e9c0cSopenharmony_ci                len: 2,
9577e2e9c0cSopenharmony_ci            },
9587e2e9c0cSopenharmony_ci            Token::Str("a"),
9597e2e9c0cSopenharmony_ci            Token::I8(1),
9607e2e9c0cSopenharmony_ci            Token::Str("c"),
9617e2e9c0cSopenharmony_ci            Token::I32(3),
9627e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
9637e2e9c0cSopenharmony_ci        ],
9647e2e9c0cSopenharmony_ci    );
9657e2e9c0cSopenharmony_ci
9667e2e9c0cSopenharmony_ci    assert_ser_tokens(
9677e2e9c0cSopenharmony_ci        &SkipSerializingEnum::Struct {
9687e2e9c0cSopenharmony_ci            a: &a,
9697e2e9c0cSopenharmony_ci            _b: 2,
9707e2e9c0cSopenharmony_ci            c: 123,
9717e2e9c0cSopenharmony_ci        },
9727e2e9c0cSopenharmony_ci        &[
9737e2e9c0cSopenharmony_ci            Token::StructVariant {
9747e2e9c0cSopenharmony_ci                name: "SkipSerializingEnum",
9757e2e9c0cSopenharmony_ci                variant: "Struct",
9767e2e9c0cSopenharmony_ci                len: 1,
9777e2e9c0cSopenharmony_ci            },
9787e2e9c0cSopenharmony_ci            Token::Str("a"),
9797e2e9c0cSopenharmony_ci            Token::I8(1),
9807e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
9817e2e9c0cSopenharmony_ci        ],
9827e2e9c0cSopenharmony_ci    );
9837e2e9c0cSopenharmony_ci
9847e2e9c0cSopenharmony_ci    assert_ser_tokens(
9857e2e9c0cSopenharmony_ci        &SkipSerializingEnum::Tuple(&a, 2, 3),
9867e2e9c0cSopenharmony_ci        &[
9877e2e9c0cSopenharmony_ci            Token::TupleVariant {
9887e2e9c0cSopenharmony_ci                name: "SkipSerializingEnum",
9897e2e9c0cSopenharmony_ci                variant: "Tuple",
9907e2e9c0cSopenharmony_ci                len: 2,
9917e2e9c0cSopenharmony_ci            },
9927e2e9c0cSopenharmony_ci            Token::I8(1),
9937e2e9c0cSopenharmony_ci            Token::I32(3),
9947e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
9957e2e9c0cSopenharmony_ci        ],
9967e2e9c0cSopenharmony_ci    );
9977e2e9c0cSopenharmony_ci
9987e2e9c0cSopenharmony_ci    assert_ser_tokens(
9997e2e9c0cSopenharmony_ci        &SkipSerializingEnum::Tuple(&a, 2, 123),
10007e2e9c0cSopenharmony_ci        &[
10017e2e9c0cSopenharmony_ci            Token::TupleVariant {
10027e2e9c0cSopenharmony_ci                name: "SkipSerializingEnum",
10037e2e9c0cSopenharmony_ci                variant: "Tuple",
10047e2e9c0cSopenharmony_ci                len: 1,
10057e2e9c0cSopenharmony_ci            },
10067e2e9c0cSopenharmony_ci            Token::I8(1),
10077e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
10087e2e9c0cSopenharmony_ci        ],
10097e2e9c0cSopenharmony_ci    );
10107e2e9c0cSopenharmony_ci}
10117e2e9c0cSopenharmony_ci
10127e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq)]
10137e2e9c0cSopenharmony_cistruct NotSerializeStruct(i8);
10147e2e9c0cSopenharmony_ci
10157e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq)]
10167e2e9c0cSopenharmony_cienum NotSerializeEnum {
10177e2e9c0cSopenharmony_ci    Trouble,
10187e2e9c0cSopenharmony_ci}
10197e2e9c0cSopenharmony_ci
10207e2e9c0cSopenharmony_ciimpl SerializeWith for NotSerializeEnum {
10217e2e9c0cSopenharmony_ci    fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
10227e2e9c0cSopenharmony_ci    where
10237e2e9c0cSopenharmony_ci        S: Serializer,
10247e2e9c0cSopenharmony_ci    {
10257e2e9c0cSopenharmony_ci        "trouble".serialize(ser)
10267e2e9c0cSopenharmony_ci    }
10277e2e9c0cSopenharmony_ci}
10287e2e9c0cSopenharmony_ci
10297e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
10307e2e9c0cSopenharmony_cistruct ContainsNotSerialize<'a, B, C, D>
10317e2e9c0cSopenharmony_ciwhere
10327e2e9c0cSopenharmony_ci    B: 'a,
10337e2e9c0cSopenharmony_ci    D: SerializeWith,
10347e2e9c0cSopenharmony_ci{
10357e2e9c0cSopenharmony_ci    a: &'a Option<i8>,
10367e2e9c0cSopenharmony_ci    #[serde(skip_serializing)]
10377e2e9c0cSopenharmony_ci    b: &'a B,
10387e2e9c0cSopenharmony_ci    #[serde(skip_serializing)]
10397e2e9c0cSopenharmony_ci    c: Option<C>,
10407e2e9c0cSopenharmony_ci    #[serde(serialize_with = "SerializeWith::serialize_with")]
10417e2e9c0cSopenharmony_ci    d: D,
10427e2e9c0cSopenharmony_ci}
10437e2e9c0cSopenharmony_ci
10447e2e9c0cSopenharmony_ci#[test]
10457e2e9c0cSopenharmony_cifn test_elt_not_serialize() {
10467e2e9c0cSopenharmony_ci    let a = 1;
10477e2e9c0cSopenharmony_ci    assert_ser_tokens(
10487e2e9c0cSopenharmony_ci        &ContainsNotSerialize {
10497e2e9c0cSopenharmony_ci            a: &Some(a),
10507e2e9c0cSopenharmony_ci            b: &NotSerializeStruct(2),
10517e2e9c0cSopenharmony_ci            c: Some(NotSerializeEnum::Trouble),
10527e2e9c0cSopenharmony_ci            d: NotSerializeEnum::Trouble,
10537e2e9c0cSopenharmony_ci        },
10547e2e9c0cSopenharmony_ci        &[
10557e2e9c0cSopenharmony_ci            Token::Struct {
10567e2e9c0cSopenharmony_ci                name: "ContainsNotSerialize",
10577e2e9c0cSopenharmony_ci                len: 2,
10587e2e9c0cSopenharmony_ci            },
10597e2e9c0cSopenharmony_ci            Token::Str("a"),
10607e2e9c0cSopenharmony_ci            Token::Some,
10617e2e9c0cSopenharmony_ci            Token::I8(1),
10627e2e9c0cSopenharmony_ci            Token::Str("d"),
10637e2e9c0cSopenharmony_ci            Token::Str("trouble"),
10647e2e9c0cSopenharmony_ci            Token::StructEnd,
10657e2e9c0cSopenharmony_ci        ],
10667e2e9c0cSopenharmony_ci    );
10677e2e9c0cSopenharmony_ci}
10687e2e9c0cSopenharmony_ci
10697e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
10707e2e9c0cSopenharmony_cistruct SerializeWithStruct<'a, B>
10717e2e9c0cSopenharmony_ciwhere
10727e2e9c0cSopenharmony_ci    B: SerializeWith,
10737e2e9c0cSopenharmony_ci{
10747e2e9c0cSopenharmony_ci    a: &'a i8,
10757e2e9c0cSopenharmony_ci    #[serde(serialize_with = "SerializeWith::serialize_with")]
10767e2e9c0cSopenharmony_ci    b: B,
10777e2e9c0cSopenharmony_ci}
10787e2e9c0cSopenharmony_ci
10797e2e9c0cSopenharmony_ci#[test]
10807e2e9c0cSopenharmony_cifn test_serialize_with_struct() {
10817e2e9c0cSopenharmony_ci    let a = 1;
10827e2e9c0cSopenharmony_ci    assert_ser_tokens(
10837e2e9c0cSopenharmony_ci        &SerializeWithStruct { a: &a, b: 2 },
10847e2e9c0cSopenharmony_ci        &[
10857e2e9c0cSopenharmony_ci            Token::Struct {
10867e2e9c0cSopenharmony_ci                name: "SerializeWithStruct",
10877e2e9c0cSopenharmony_ci                len: 2,
10887e2e9c0cSopenharmony_ci            },
10897e2e9c0cSopenharmony_ci            Token::Str("a"),
10907e2e9c0cSopenharmony_ci            Token::I8(1),
10917e2e9c0cSopenharmony_ci            Token::Str("b"),
10927e2e9c0cSopenharmony_ci            Token::Bool(false),
10937e2e9c0cSopenharmony_ci            Token::StructEnd,
10947e2e9c0cSopenharmony_ci        ],
10957e2e9c0cSopenharmony_ci    );
10967e2e9c0cSopenharmony_ci
10977e2e9c0cSopenharmony_ci    assert_ser_tokens(
10987e2e9c0cSopenharmony_ci        &SerializeWithStruct { a: &a, b: 123 },
10997e2e9c0cSopenharmony_ci        &[
11007e2e9c0cSopenharmony_ci            Token::Struct {
11017e2e9c0cSopenharmony_ci                name: "SerializeWithStruct",
11027e2e9c0cSopenharmony_ci                len: 2,
11037e2e9c0cSopenharmony_ci            },
11047e2e9c0cSopenharmony_ci            Token::Str("a"),
11057e2e9c0cSopenharmony_ci            Token::I8(1),
11067e2e9c0cSopenharmony_ci            Token::Str("b"),
11077e2e9c0cSopenharmony_ci            Token::Bool(true),
11087e2e9c0cSopenharmony_ci            Token::StructEnd,
11097e2e9c0cSopenharmony_ci        ],
11107e2e9c0cSopenharmony_ci    );
11117e2e9c0cSopenharmony_ci}
11127e2e9c0cSopenharmony_ci
11137e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
11147e2e9c0cSopenharmony_cienum SerializeWithEnum<'a, B>
11157e2e9c0cSopenharmony_ciwhere
11167e2e9c0cSopenharmony_ci    B: SerializeWith,
11177e2e9c0cSopenharmony_ci{
11187e2e9c0cSopenharmony_ci    Struct {
11197e2e9c0cSopenharmony_ci        a: &'a i8,
11207e2e9c0cSopenharmony_ci        #[serde(serialize_with = "SerializeWith::serialize_with")]
11217e2e9c0cSopenharmony_ci        b: B,
11227e2e9c0cSopenharmony_ci    },
11237e2e9c0cSopenharmony_ci}
11247e2e9c0cSopenharmony_ci
11257e2e9c0cSopenharmony_ci#[test]
11267e2e9c0cSopenharmony_cifn test_serialize_with_enum() {
11277e2e9c0cSopenharmony_ci    let a = 1;
11287e2e9c0cSopenharmony_ci    assert_ser_tokens(
11297e2e9c0cSopenharmony_ci        &SerializeWithEnum::Struct { a: &a, b: 2 },
11307e2e9c0cSopenharmony_ci        &[
11317e2e9c0cSopenharmony_ci            Token::StructVariant {
11327e2e9c0cSopenharmony_ci                name: "SerializeWithEnum",
11337e2e9c0cSopenharmony_ci                variant: "Struct",
11347e2e9c0cSopenharmony_ci                len: 2,
11357e2e9c0cSopenharmony_ci            },
11367e2e9c0cSopenharmony_ci            Token::Str("a"),
11377e2e9c0cSopenharmony_ci            Token::I8(1),
11387e2e9c0cSopenharmony_ci            Token::Str("b"),
11397e2e9c0cSopenharmony_ci            Token::Bool(false),
11407e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
11417e2e9c0cSopenharmony_ci        ],
11427e2e9c0cSopenharmony_ci    );
11437e2e9c0cSopenharmony_ci
11447e2e9c0cSopenharmony_ci    assert_ser_tokens(
11457e2e9c0cSopenharmony_ci        &SerializeWithEnum::Struct { a: &a, b: 123 },
11467e2e9c0cSopenharmony_ci        &[
11477e2e9c0cSopenharmony_ci            Token::StructVariant {
11487e2e9c0cSopenharmony_ci                name: "SerializeWithEnum",
11497e2e9c0cSopenharmony_ci                variant: "Struct",
11507e2e9c0cSopenharmony_ci                len: 2,
11517e2e9c0cSopenharmony_ci            },
11527e2e9c0cSopenharmony_ci            Token::Str("a"),
11537e2e9c0cSopenharmony_ci            Token::I8(1),
11547e2e9c0cSopenharmony_ci            Token::Str("b"),
11557e2e9c0cSopenharmony_ci            Token::Bool(true),
11567e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
11577e2e9c0cSopenharmony_ci        ],
11587e2e9c0cSopenharmony_ci    );
11597e2e9c0cSopenharmony_ci}
11607e2e9c0cSopenharmony_ci
11617e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
11627e2e9c0cSopenharmony_cienum WithVariant {
11637e2e9c0cSopenharmony_ci    #[serde(serialize_with = "serialize_unit_variant_as_i8")]
11647e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "deserialize_i8_as_unit_variant")]
11657e2e9c0cSopenharmony_ci    Unit,
11667e2e9c0cSopenharmony_ci
11677e2e9c0cSopenharmony_ci    #[serde(serialize_with = "SerializeWith::serialize_with")]
11687e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
11697e2e9c0cSopenharmony_ci    Newtype(i32),
11707e2e9c0cSopenharmony_ci
11717e2e9c0cSopenharmony_ci    #[serde(serialize_with = "serialize_variant_as_string")]
11727e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "deserialize_string_as_variant")]
11737e2e9c0cSopenharmony_ci    Tuple(String, u8),
11747e2e9c0cSopenharmony_ci
11757e2e9c0cSopenharmony_ci    #[serde(serialize_with = "serialize_variant_as_string")]
11767e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "deserialize_string_as_variant")]
11777e2e9c0cSopenharmony_ci    Struct { f1: String, f2: u8 },
11787e2e9c0cSopenharmony_ci}
11797e2e9c0cSopenharmony_ci
11807e2e9c0cSopenharmony_cifn serialize_unit_variant_as_i8<S>(serializer: S) -> Result<S::Ok, S::Error>
11817e2e9c0cSopenharmony_ciwhere
11827e2e9c0cSopenharmony_ci    S: Serializer,
11837e2e9c0cSopenharmony_ci{
11847e2e9c0cSopenharmony_ci    serializer.serialize_i8(0)
11857e2e9c0cSopenharmony_ci}
11867e2e9c0cSopenharmony_ci
11877e2e9c0cSopenharmony_cifn deserialize_i8_as_unit_variant<'de, D>(deserializer: D) -> Result<(), D::Error>
11887e2e9c0cSopenharmony_ciwhere
11897e2e9c0cSopenharmony_ci    D: Deserializer<'de>,
11907e2e9c0cSopenharmony_ci{
11917e2e9c0cSopenharmony_ci    let n = i8::deserialize(deserializer)?;
11927e2e9c0cSopenharmony_ci    match n {
11937e2e9c0cSopenharmony_ci        0 => Ok(()),
11947e2e9c0cSopenharmony_ci        _ => Err(de::Error::invalid_value(Unexpected::Signed(n as i64), &"0")),
11957e2e9c0cSopenharmony_ci    }
11967e2e9c0cSopenharmony_ci}
11977e2e9c0cSopenharmony_ci
11987e2e9c0cSopenharmony_cifn serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S::Ok, S::Error>
11997e2e9c0cSopenharmony_ciwhere
12007e2e9c0cSopenharmony_ci    S: Serializer,
12017e2e9c0cSopenharmony_ci{
12027e2e9c0cSopenharmony_ci    serializer.collect_str(&format_args!("{};{:?}", f1, f2))
12037e2e9c0cSopenharmony_ci}
12047e2e9c0cSopenharmony_ci
12057e2e9c0cSopenharmony_cifn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error>
12067e2e9c0cSopenharmony_ciwhere
12077e2e9c0cSopenharmony_ci    D: Deserializer<'de>,
12087e2e9c0cSopenharmony_ci{
12097e2e9c0cSopenharmony_ci    let s = String::deserialize(deserializer)?;
12107e2e9c0cSopenharmony_ci    let mut pieces = s.split(';');
12117e2e9c0cSopenharmony_ci    let Some(f1) = pieces.next() else {
12127e2e9c0cSopenharmony_ci        return Err(de::Error::invalid_length(0, &"2"));
12137e2e9c0cSopenharmony_ci    };
12147e2e9c0cSopenharmony_ci    let Some(f2) = pieces.next() else {
12157e2e9c0cSopenharmony_ci        return Err(de::Error::invalid_length(1, &"2"));
12167e2e9c0cSopenharmony_ci    };
12177e2e9c0cSopenharmony_ci    let Ok(f2) = f2.parse() else {
12187e2e9c0cSopenharmony_ci        return Err(de::Error::invalid_value(
12197e2e9c0cSopenharmony_ci            Unexpected::Str(f2),
12207e2e9c0cSopenharmony_ci            &"an 8-bit signed integer",
12217e2e9c0cSopenharmony_ci        ));
12227e2e9c0cSopenharmony_ci    };
12237e2e9c0cSopenharmony_ci    Ok((f1.into(), f2))
12247e2e9c0cSopenharmony_ci}
12257e2e9c0cSopenharmony_ci
12267e2e9c0cSopenharmony_ci#[test]
12277e2e9c0cSopenharmony_cifn test_serialize_with_variant() {
12287e2e9c0cSopenharmony_ci    assert_ser_tokens(
12297e2e9c0cSopenharmony_ci        &WithVariant::Unit,
12307e2e9c0cSopenharmony_ci        &[
12317e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12327e2e9c0cSopenharmony_ci                name: "WithVariant",
12337e2e9c0cSopenharmony_ci                variant: "Unit",
12347e2e9c0cSopenharmony_ci            },
12357e2e9c0cSopenharmony_ci            Token::I8(0),
12367e2e9c0cSopenharmony_ci        ],
12377e2e9c0cSopenharmony_ci    );
12387e2e9c0cSopenharmony_ci
12397e2e9c0cSopenharmony_ci    assert_ser_tokens(
12407e2e9c0cSopenharmony_ci        &WithVariant::Newtype(123),
12417e2e9c0cSopenharmony_ci        &[
12427e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12437e2e9c0cSopenharmony_ci                name: "WithVariant",
12447e2e9c0cSopenharmony_ci                variant: "Newtype",
12457e2e9c0cSopenharmony_ci            },
12467e2e9c0cSopenharmony_ci            Token::Bool(true),
12477e2e9c0cSopenharmony_ci        ],
12487e2e9c0cSopenharmony_ci    );
12497e2e9c0cSopenharmony_ci
12507e2e9c0cSopenharmony_ci    assert_ser_tokens(
12517e2e9c0cSopenharmony_ci        &WithVariant::Tuple("hello".into(), 0),
12527e2e9c0cSopenharmony_ci        &[
12537e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12547e2e9c0cSopenharmony_ci                name: "WithVariant",
12557e2e9c0cSopenharmony_ci                variant: "Tuple",
12567e2e9c0cSopenharmony_ci            },
12577e2e9c0cSopenharmony_ci            Token::Str("hello;0"),
12587e2e9c0cSopenharmony_ci        ],
12597e2e9c0cSopenharmony_ci    );
12607e2e9c0cSopenharmony_ci
12617e2e9c0cSopenharmony_ci    assert_ser_tokens(
12627e2e9c0cSopenharmony_ci        &WithVariant::Struct {
12637e2e9c0cSopenharmony_ci            f1: "world".into(),
12647e2e9c0cSopenharmony_ci            f2: 1,
12657e2e9c0cSopenharmony_ci        },
12667e2e9c0cSopenharmony_ci        &[
12677e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12687e2e9c0cSopenharmony_ci                name: "WithVariant",
12697e2e9c0cSopenharmony_ci                variant: "Struct",
12707e2e9c0cSopenharmony_ci            },
12717e2e9c0cSopenharmony_ci            Token::Str("world;1"),
12727e2e9c0cSopenharmony_ci        ],
12737e2e9c0cSopenharmony_ci    );
12747e2e9c0cSopenharmony_ci}
12757e2e9c0cSopenharmony_ci
12767e2e9c0cSopenharmony_ci#[test]
12777e2e9c0cSopenharmony_cifn test_deserialize_with_variant() {
12787e2e9c0cSopenharmony_ci    assert_de_tokens(
12797e2e9c0cSopenharmony_ci        &WithVariant::Unit,
12807e2e9c0cSopenharmony_ci        &[
12817e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12827e2e9c0cSopenharmony_ci                name: "WithVariant",
12837e2e9c0cSopenharmony_ci                variant: "Unit",
12847e2e9c0cSopenharmony_ci            },
12857e2e9c0cSopenharmony_ci            Token::I8(0),
12867e2e9c0cSopenharmony_ci        ],
12877e2e9c0cSopenharmony_ci    );
12887e2e9c0cSopenharmony_ci
12897e2e9c0cSopenharmony_ci    assert_de_tokens(
12907e2e9c0cSopenharmony_ci        &WithVariant::Newtype(123),
12917e2e9c0cSopenharmony_ci        &[
12927e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
12937e2e9c0cSopenharmony_ci                name: "WithVariant",
12947e2e9c0cSopenharmony_ci                variant: "Newtype",
12957e2e9c0cSopenharmony_ci            },
12967e2e9c0cSopenharmony_ci            Token::Bool(true),
12977e2e9c0cSopenharmony_ci        ],
12987e2e9c0cSopenharmony_ci    );
12997e2e9c0cSopenharmony_ci
13007e2e9c0cSopenharmony_ci    assert_de_tokens(
13017e2e9c0cSopenharmony_ci        &WithVariant::Tuple("hello".into(), 0),
13027e2e9c0cSopenharmony_ci        &[
13037e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
13047e2e9c0cSopenharmony_ci                name: "WithVariant",
13057e2e9c0cSopenharmony_ci                variant: "Tuple",
13067e2e9c0cSopenharmony_ci            },
13077e2e9c0cSopenharmony_ci            Token::Str("hello;0"),
13087e2e9c0cSopenharmony_ci        ],
13097e2e9c0cSopenharmony_ci    );
13107e2e9c0cSopenharmony_ci
13117e2e9c0cSopenharmony_ci    assert_de_tokens(
13127e2e9c0cSopenharmony_ci        &WithVariant::Struct {
13137e2e9c0cSopenharmony_ci            f1: "world".into(),
13147e2e9c0cSopenharmony_ci            f2: 1,
13157e2e9c0cSopenharmony_ci        },
13167e2e9c0cSopenharmony_ci        &[
13177e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
13187e2e9c0cSopenharmony_ci                name: "WithVariant",
13197e2e9c0cSopenharmony_ci                variant: "Struct",
13207e2e9c0cSopenharmony_ci            },
13217e2e9c0cSopenharmony_ci            Token::Str("world;1"),
13227e2e9c0cSopenharmony_ci        ],
13237e2e9c0cSopenharmony_ci    );
13247e2e9c0cSopenharmony_ci}
13257e2e9c0cSopenharmony_ci
13267e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
13277e2e9c0cSopenharmony_cistruct DeserializeWithStruct<B>
13287e2e9c0cSopenharmony_ciwhere
13297e2e9c0cSopenharmony_ci    B: DeserializeWith,
13307e2e9c0cSopenharmony_ci{
13317e2e9c0cSopenharmony_ci    a: i8,
13327e2e9c0cSopenharmony_ci    #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
13337e2e9c0cSopenharmony_ci    b: B,
13347e2e9c0cSopenharmony_ci}
13357e2e9c0cSopenharmony_ci
13367e2e9c0cSopenharmony_ci#[test]
13377e2e9c0cSopenharmony_cifn test_deserialize_with_struct() {
13387e2e9c0cSopenharmony_ci    assert_de_tokens(
13397e2e9c0cSopenharmony_ci        &DeserializeWithStruct { a: 1, b: 2 },
13407e2e9c0cSopenharmony_ci        &[
13417e2e9c0cSopenharmony_ci            Token::Struct {
13427e2e9c0cSopenharmony_ci                name: "DeserializeWithStruct",
13437e2e9c0cSopenharmony_ci                len: 2,
13447e2e9c0cSopenharmony_ci            },
13457e2e9c0cSopenharmony_ci            Token::Str("a"),
13467e2e9c0cSopenharmony_ci            Token::I8(1),
13477e2e9c0cSopenharmony_ci            Token::Str("b"),
13487e2e9c0cSopenharmony_ci            Token::Bool(false),
13497e2e9c0cSopenharmony_ci            Token::StructEnd,
13507e2e9c0cSopenharmony_ci        ],
13517e2e9c0cSopenharmony_ci    );
13527e2e9c0cSopenharmony_ci
13537e2e9c0cSopenharmony_ci    assert_de_tokens(
13547e2e9c0cSopenharmony_ci        &DeserializeWithStruct { a: 1, b: 123 },
13557e2e9c0cSopenharmony_ci        &[
13567e2e9c0cSopenharmony_ci            Token::Struct {
13577e2e9c0cSopenharmony_ci                name: "DeserializeWithStruct",
13587e2e9c0cSopenharmony_ci                len: 2,
13597e2e9c0cSopenharmony_ci            },
13607e2e9c0cSopenharmony_ci            Token::Str("a"),
13617e2e9c0cSopenharmony_ci            Token::I8(1),
13627e2e9c0cSopenharmony_ci            Token::Str("b"),
13637e2e9c0cSopenharmony_ci            Token::Bool(true),
13647e2e9c0cSopenharmony_ci            Token::StructEnd,
13657e2e9c0cSopenharmony_ci        ],
13667e2e9c0cSopenharmony_ci    );
13677e2e9c0cSopenharmony_ci}
13687e2e9c0cSopenharmony_ci
13697e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
13707e2e9c0cSopenharmony_cienum DeserializeWithEnum<B>
13717e2e9c0cSopenharmony_ciwhere
13727e2e9c0cSopenharmony_ci    B: DeserializeWith,
13737e2e9c0cSopenharmony_ci{
13747e2e9c0cSopenharmony_ci    Struct {
13757e2e9c0cSopenharmony_ci        a: i8,
13767e2e9c0cSopenharmony_ci        #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
13777e2e9c0cSopenharmony_ci        b: B,
13787e2e9c0cSopenharmony_ci    },
13797e2e9c0cSopenharmony_ci}
13807e2e9c0cSopenharmony_ci
13817e2e9c0cSopenharmony_ci#[test]
13827e2e9c0cSopenharmony_cifn test_deserialize_with_enum() {
13837e2e9c0cSopenharmony_ci    assert_de_tokens(
13847e2e9c0cSopenharmony_ci        &DeserializeWithEnum::Struct { a: 1, b: 2 },
13857e2e9c0cSopenharmony_ci        &[
13867e2e9c0cSopenharmony_ci            Token::StructVariant {
13877e2e9c0cSopenharmony_ci                name: "DeserializeWithEnum",
13887e2e9c0cSopenharmony_ci                variant: "Struct",
13897e2e9c0cSopenharmony_ci                len: 2,
13907e2e9c0cSopenharmony_ci            },
13917e2e9c0cSopenharmony_ci            Token::Str("a"),
13927e2e9c0cSopenharmony_ci            Token::I8(1),
13937e2e9c0cSopenharmony_ci            Token::Str("b"),
13947e2e9c0cSopenharmony_ci            Token::Bool(false),
13957e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
13967e2e9c0cSopenharmony_ci        ],
13977e2e9c0cSopenharmony_ci    );
13987e2e9c0cSopenharmony_ci
13997e2e9c0cSopenharmony_ci    assert_de_tokens(
14007e2e9c0cSopenharmony_ci        &DeserializeWithEnum::Struct { a: 1, b: 123 },
14017e2e9c0cSopenharmony_ci        &[
14027e2e9c0cSopenharmony_ci            Token::StructVariant {
14037e2e9c0cSopenharmony_ci                name: "DeserializeWithEnum",
14047e2e9c0cSopenharmony_ci                variant: "Struct",
14057e2e9c0cSopenharmony_ci                len: 2,
14067e2e9c0cSopenharmony_ci            },
14077e2e9c0cSopenharmony_ci            Token::Str("a"),
14087e2e9c0cSopenharmony_ci            Token::I8(1),
14097e2e9c0cSopenharmony_ci            Token::Str("b"),
14107e2e9c0cSopenharmony_ci            Token::Bool(true),
14117e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
14127e2e9c0cSopenharmony_ci        ],
14137e2e9c0cSopenharmony_ci    );
14147e2e9c0cSopenharmony_ci}
14157e2e9c0cSopenharmony_ci
14167e2e9c0cSopenharmony_ci#[test]
14177e2e9c0cSopenharmony_cifn test_missing_renamed_field_struct() {
14187e2e9c0cSopenharmony_ci    assert_de_tokens_error::<RenameStruct>(
14197e2e9c0cSopenharmony_ci        &[
14207e2e9c0cSopenharmony_ci            Token::Struct {
14217e2e9c0cSopenharmony_ci                name: "Superhero",
14227e2e9c0cSopenharmony_ci                len: 2,
14237e2e9c0cSopenharmony_ci            },
14247e2e9c0cSopenharmony_ci            Token::Str("a1"),
14257e2e9c0cSopenharmony_ci            Token::I32(1),
14267e2e9c0cSopenharmony_ci            Token::StructEnd,
14277e2e9c0cSopenharmony_ci        ],
14287e2e9c0cSopenharmony_ci        "missing field `a3`",
14297e2e9c0cSopenharmony_ci    );
14307e2e9c0cSopenharmony_ci
14317e2e9c0cSopenharmony_ci    assert_de_tokens_error::<RenameStructSerializeDeserialize>(
14327e2e9c0cSopenharmony_ci        &[
14337e2e9c0cSopenharmony_ci            Token::Struct {
14347e2e9c0cSopenharmony_ci                name: "SuperheroDe",
14357e2e9c0cSopenharmony_ci                len: 2,
14367e2e9c0cSopenharmony_ci            },
14377e2e9c0cSopenharmony_ci            Token::Str("a1"),
14387e2e9c0cSopenharmony_ci            Token::I32(1),
14397e2e9c0cSopenharmony_ci            Token::StructEnd,
14407e2e9c0cSopenharmony_ci        ],
14417e2e9c0cSopenharmony_ci        "missing field `a5`",
14427e2e9c0cSopenharmony_ci    );
14437e2e9c0cSopenharmony_ci}
14447e2e9c0cSopenharmony_ci
14457e2e9c0cSopenharmony_ci#[test]
14467e2e9c0cSopenharmony_cifn test_missing_renamed_field_enum() {
14477e2e9c0cSopenharmony_ci    assert_de_tokens_error::<RenameEnum>(
14487e2e9c0cSopenharmony_ci        &[
14497e2e9c0cSopenharmony_ci            Token::StructVariant {
14507e2e9c0cSopenharmony_ci                name: "Superhero",
14517e2e9c0cSopenharmony_ci                variant: "barry_allan",
14527e2e9c0cSopenharmony_ci                len: 1,
14537e2e9c0cSopenharmony_ci            },
14547e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
14557e2e9c0cSopenharmony_ci        ],
14567e2e9c0cSopenharmony_ci        "missing field `b`",
14577e2e9c0cSopenharmony_ci    );
14587e2e9c0cSopenharmony_ci
14597e2e9c0cSopenharmony_ci    assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
14607e2e9c0cSopenharmony_ci        &[
14617e2e9c0cSopenharmony_ci            Token::StructVariant {
14627e2e9c0cSopenharmony_ci                name: "SuperheroDe",
14637e2e9c0cSopenharmony_ci                variant: "jason_todd",
14647e2e9c0cSopenharmony_ci                len: 2,
14657e2e9c0cSopenharmony_ci            },
14667e2e9c0cSopenharmony_ci            Token::Str("a"),
14677e2e9c0cSopenharmony_ci            Token::I8(0),
14687e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
14697e2e9c0cSopenharmony_ci        ],
14707e2e9c0cSopenharmony_ci        "missing field `d`",
14717e2e9c0cSopenharmony_ci    );
14727e2e9c0cSopenharmony_ci}
14737e2e9c0cSopenharmony_ci
14747e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
14757e2e9c0cSopenharmony_cienum InvalidLengthEnum {
14767e2e9c0cSopenharmony_ci    A(i32, i32, i32),
14777e2e9c0cSopenharmony_ci    B(#[serde(skip_deserializing)] i32, i32, i32),
14787e2e9c0cSopenharmony_ci}
14797e2e9c0cSopenharmony_ci
14807e2e9c0cSopenharmony_ci#[test]
14817e2e9c0cSopenharmony_cifn test_invalid_length_enum() {
14827e2e9c0cSopenharmony_ci    assert_de_tokens_error::<InvalidLengthEnum>(
14837e2e9c0cSopenharmony_ci        &[
14847e2e9c0cSopenharmony_ci            Token::TupleVariant {
14857e2e9c0cSopenharmony_ci                name: "InvalidLengthEnum",
14867e2e9c0cSopenharmony_ci                variant: "A",
14877e2e9c0cSopenharmony_ci                len: 3,
14887e2e9c0cSopenharmony_ci            },
14897e2e9c0cSopenharmony_ci            Token::I32(1),
14907e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
14917e2e9c0cSopenharmony_ci        ],
14927e2e9c0cSopenharmony_ci        "invalid length 1, expected tuple variant InvalidLengthEnum::A with 3 elements",
14937e2e9c0cSopenharmony_ci    );
14947e2e9c0cSopenharmony_ci    assert_de_tokens_error::<InvalidLengthEnum>(
14957e2e9c0cSopenharmony_ci        &[
14967e2e9c0cSopenharmony_ci            Token::TupleVariant {
14977e2e9c0cSopenharmony_ci                name: "InvalidLengthEnum",
14987e2e9c0cSopenharmony_ci                variant: "B",
14997e2e9c0cSopenharmony_ci                len: 2,
15007e2e9c0cSopenharmony_ci            },
15017e2e9c0cSopenharmony_ci            Token::I32(1),
15027e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
15037e2e9c0cSopenharmony_ci        ],
15047e2e9c0cSopenharmony_ci        "invalid length 1, expected tuple variant InvalidLengthEnum::B with 2 elements",
15057e2e9c0cSopenharmony_ci    );
15067e2e9c0cSopenharmony_ci}
15077e2e9c0cSopenharmony_ci
15087e2e9c0cSopenharmony_ci#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
15097e2e9c0cSopenharmony_ci#[serde(into = "EnumToU32", from = "EnumToU32")]
15107e2e9c0cSopenharmony_cistruct StructFromEnum(Option<u32>);
15117e2e9c0cSopenharmony_ci
15127e2e9c0cSopenharmony_ciimpl Into<EnumToU32> for StructFromEnum {
15137e2e9c0cSopenharmony_ci    fn into(self) -> EnumToU32 {
15147e2e9c0cSopenharmony_ci        match self {
15157e2e9c0cSopenharmony_ci            StructFromEnum(v) => v.into(),
15167e2e9c0cSopenharmony_ci        }
15177e2e9c0cSopenharmony_ci    }
15187e2e9c0cSopenharmony_ci}
15197e2e9c0cSopenharmony_ci
15207e2e9c0cSopenharmony_ciimpl From<EnumToU32> for StructFromEnum {
15217e2e9c0cSopenharmony_ci    fn from(v: EnumToU32) -> Self {
15227e2e9c0cSopenharmony_ci        StructFromEnum(v.into())
15237e2e9c0cSopenharmony_ci    }
15247e2e9c0cSopenharmony_ci}
15257e2e9c0cSopenharmony_ci
15267e2e9c0cSopenharmony_ci#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
15277e2e9c0cSopenharmony_ci#[serde(into = "Option<u32>", from = "Option<u32>")]
15287e2e9c0cSopenharmony_cienum EnumToU32 {
15297e2e9c0cSopenharmony_ci    One,
15307e2e9c0cSopenharmony_ci    Two,
15317e2e9c0cSopenharmony_ci    Three,
15327e2e9c0cSopenharmony_ci    Four,
15337e2e9c0cSopenharmony_ci    Nothing,
15347e2e9c0cSopenharmony_ci}
15357e2e9c0cSopenharmony_ci
15367e2e9c0cSopenharmony_ciimpl Into<Option<u32>> for EnumToU32 {
15377e2e9c0cSopenharmony_ci    fn into(self) -> Option<u32> {
15387e2e9c0cSopenharmony_ci        match self {
15397e2e9c0cSopenharmony_ci            EnumToU32::One => Some(1),
15407e2e9c0cSopenharmony_ci            EnumToU32::Two => Some(2),
15417e2e9c0cSopenharmony_ci            EnumToU32::Three => Some(3),
15427e2e9c0cSopenharmony_ci            EnumToU32::Four => Some(4),
15437e2e9c0cSopenharmony_ci            EnumToU32::Nothing => None,
15447e2e9c0cSopenharmony_ci        }
15457e2e9c0cSopenharmony_ci    }
15467e2e9c0cSopenharmony_ci}
15477e2e9c0cSopenharmony_ci
15487e2e9c0cSopenharmony_ciimpl From<Option<u32>> for EnumToU32 {
15497e2e9c0cSopenharmony_ci    fn from(v: Option<u32>) -> Self {
15507e2e9c0cSopenharmony_ci        match v {
15517e2e9c0cSopenharmony_ci            Some(1) => EnumToU32::One,
15527e2e9c0cSopenharmony_ci            Some(2) => EnumToU32::Two,
15537e2e9c0cSopenharmony_ci            Some(3) => EnumToU32::Three,
15547e2e9c0cSopenharmony_ci            Some(4) => EnumToU32::Four,
15557e2e9c0cSopenharmony_ci            _ => EnumToU32::Nothing,
15567e2e9c0cSopenharmony_ci        }
15577e2e9c0cSopenharmony_ci    }
15587e2e9c0cSopenharmony_ci}
15597e2e9c0cSopenharmony_ci
15607e2e9c0cSopenharmony_ci#[derive(Clone, Deserialize, PartialEq, Debug)]
15617e2e9c0cSopenharmony_ci#[serde(try_from = "u32")]
15627e2e9c0cSopenharmony_cienum TryFromU32 {
15637e2e9c0cSopenharmony_ci    One,
15647e2e9c0cSopenharmony_ci    Two,
15657e2e9c0cSopenharmony_ci}
15667e2e9c0cSopenharmony_ci
15677e2e9c0cSopenharmony_ciimpl TryFrom<u32> for TryFromU32 {
15687e2e9c0cSopenharmony_ci    type Error = String;
15697e2e9c0cSopenharmony_ci
15707e2e9c0cSopenharmony_ci    fn try_from(value: u32) -> Result<Self, Self::Error> {
15717e2e9c0cSopenharmony_ci        match value {
15727e2e9c0cSopenharmony_ci            1 => Ok(TryFromU32::One),
15737e2e9c0cSopenharmony_ci            2 => Ok(TryFromU32::Two),
15747e2e9c0cSopenharmony_ci            _ => Err("out of range".to_owned()),
15757e2e9c0cSopenharmony_ci        }
15767e2e9c0cSopenharmony_ci    }
15777e2e9c0cSopenharmony_ci}
15787e2e9c0cSopenharmony_ci
15797e2e9c0cSopenharmony_ci#[test]
15807e2e9c0cSopenharmony_cifn test_from_into_traits() {
15817e2e9c0cSopenharmony_ci    assert_ser_tokens(&EnumToU32::One, &[Token::Some, Token::U32(1)]);
15827e2e9c0cSopenharmony_ci    assert_ser_tokens(&EnumToU32::Nothing, &[Token::None]);
15837e2e9c0cSopenharmony_ci    assert_de_tokens(&EnumToU32::Two, &[Token::Some, Token::U32(2)]);
15847e2e9c0cSopenharmony_ci    assert_ser_tokens(&StructFromEnum(Some(5)), &[Token::None]);
15857e2e9c0cSopenharmony_ci    assert_ser_tokens(&StructFromEnum(None), &[Token::None]);
15867e2e9c0cSopenharmony_ci    assert_de_tokens(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]);
15877e2e9c0cSopenharmony_ci    assert_de_tokens(&TryFromU32::Two, &[Token::U32(2)]);
15887e2e9c0cSopenharmony_ci    assert_de_tokens_error::<TryFromU32>(&[Token::U32(5)], "out of range");
15897e2e9c0cSopenharmony_ci}
15907e2e9c0cSopenharmony_ci
15917e2e9c0cSopenharmony_ci#[test]
15927e2e9c0cSopenharmony_cifn test_collect_other() {
15937e2e9c0cSopenharmony_ci    let mut extra = HashMap::new();
15947e2e9c0cSopenharmony_ci    extra.insert("c".into(), 3);
15957e2e9c0cSopenharmony_ci    assert_tokens(
15967e2e9c0cSopenharmony_ci        &CollectOther { a: 1, b: 2, extra },
15977e2e9c0cSopenharmony_ci        &[
15987e2e9c0cSopenharmony_ci            Token::Map { len: None },
15997e2e9c0cSopenharmony_ci            Token::Str("a"),
16007e2e9c0cSopenharmony_ci            Token::U32(1),
16017e2e9c0cSopenharmony_ci            Token::Str("b"),
16027e2e9c0cSopenharmony_ci            Token::U32(2),
16037e2e9c0cSopenharmony_ci            Token::Str("c"),
16047e2e9c0cSopenharmony_ci            Token::U32(3),
16057e2e9c0cSopenharmony_ci            Token::MapEnd,
16067e2e9c0cSopenharmony_ci        ],
16077e2e9c0cSopenharmony_ci    );
16087e2e9c0cSopenharmony_ci}
16097e2e9c0cSopenharmony_ci
16107e2e9c0cSopenharmony_ci#[test]
16117e2e9c0cSopenharmony_cifn test_unknown_field_in_flatten() {
16127e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16137e2e9c0cSopenharmony_ci    #[serde(deny_unknown_fields)]
16147e2e9c0cSopenharmony_ci    struct Outer {
16157e2e9c0cSopenharmony_ci        dummy: String,
16167e2e9c0cSopenharmony_ci        #[serde(flatten)]
16177e2e9c0cSopenharmony_ci        inner: Inner,
16187e2e9c0cSopenharmony_ci    }
16197e2e9c0cSopenharmony_ci
16207e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16217e2e9c0cSopenharmony_ci    struct Inner {
16227e2e9c0cSopenharmony_ci        foo: HashMap<String, u32>,
16237e2e9c0cSopenharmony_ci    }
16247e2e9c0cSopenharmony_ci
16257e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Outer>(
16267e2e9c0cSopenharmony_ci        &[
16277e2e9c0cSopenharmony_ci            Token::Struct {
16287e2e9c0cSopenharmony_ci                name: "Outer",
16297e2e9c0cSopenharmony_ci                len: 1,
16307e2e9c0cSopenharmony_ci            },
16317e2e9c0cSopenharmony_ci            Token::Str("dummy"),
16327e2e9c0cSopenharmony_ci            Token::Str("23"),
16337e2e9c0cSopenharmony_ci            Token::Str("foo"),
16347e2e9c0cSopenharmony_ci            Token::Map { len: None },
16357e2e9c0cSopenharmony_ci            Token::Str("a"),
16367e2e9c0cSopenharmony_ci            Token::U32(1),
16377e2e9c0cSopenharmony_ci            Token::Str("b"),
16387e2e9c0cSopenharmony_ci            Token::U32(2),
16397e2e9c0cSopenharmony_ci            Token::MapEnd,
16407e2e9c0cSopenharmony_ci            Token::Str("bar"),
16417e2e9c0cSopenharmony_ci            Token::U32(23),
16427e2e9c0cSopenharmony_ci            Token::StructEnd,
16437e2e9c0cSopenharmony_ci        ],
16447e2e9c0cSopenharmony_ci        "unknown field `bar`",
16457e2e9c0cSopenharmony_ci    );
16467e2e9c0cSopenharmony_ci}
16477e2e9c0cSopenharmony_ci
16487e2e9c0cSopenharmony_ci#[test]
16497e2e9c0cSopenharmony_cifn test_complex_flatten() {
16507e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16517e2e9c0cSopenharmony_ci    struct Outer {
16527e2e9c0cSopenharmony_ci        y: u32,
16537e2e9c0cSopenharmony_ci        #[serde(flatten)]
16547e2e9c0cSopenharmony_ci        first: First,
16557e2e9c0cSopenharmony_ci        #[serde(flatten)]
16567e2e9c0cSopenharmony_ci        second: Second,
16577e2e9c0cSopenharmony_ci        z: u32,
16587e2e9c0cSopenharmony_ci    }
16597e2e9c0cSopenharmony_ci
16607e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16617e2e9c0cSopenharmony_ci    struct First {
16627e2e9c0cSopenharmony_ci        a: u32,
16637e2e9c0cSopenharmony_ci        b: bool,
16647e2e9c0cSopenharmony_ci        c: Vec<String>,
16657e2e9c0cSopenharmony_ci        d: String,
16667e2e9c0cSopenharmony_ci        e: Option<u64>,
16677e2e9c0cSopenharmony_ci    }
16687e2e9c0cSopenharmony_ci
16697e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16707e2e9c0cSopenharmony_ci    struct Second {
16717e2e9c0cSopenharmony_ci        f: u32,
16727e2e9c0cSopenharmony_ci    }
16737e2e9c0cSopenharmony_ci
16747e2e9c0cSopenharmony_ci    assert_de_tokens(
16757e2e9c0cSopenharmony_ci        &Outer {
16767e2e9c0cSopenharmony_ci            y: 0,
16777e2e9c0cSopenharmony_ci            first: First {
16787e2e9c0cSopenharmony_ci                a: 1,
16797e2e9c0cSopenharmony_ci                b: true,
16807e2e9c0cSopenharmony_ci                c: vec!["a".into(), "b".into()],
16817e2e9c0cSopenharmony_ci                d: "c".into(),
16827e2e9c0cSopenharmony_ci                e: Some(2),
16837e2e9c0cSopenharmony_ci            },
16847e2e9c0cSopenharmony_ci            second: Second { f: 3 },
16857e2e9c0cSopenharmony_ci            z: 4,
16867e2e9c0cSopenharmony_ci        },
16877e2e9c0cSopenharmony_ci        &[
16887e2e9c0cSopenharmony_ci            Token::Map { len: None },
16897e2e9c0cSopenharmony_ci            Token::Str("y"),
16907e2e9c0cSopenharmony_ci            Token::U32(0),
16917e2e9c0cSopenharmony_ci            Token::Str("a"),
16927e2e9c0cSopenharmony_ci            Token::U32(1),
16937e2e9c0cSopenharmony_ci            Token::Str("b"),
16947e2e9c0cSopenharmony_ci            Token::Bool(true),
16957e2e9c0cSopenharmony_ci            Token::Str("c"),
16967e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
16977e2e9c0cSopenharmony_ci            Token::Str("a"),
16987e2e9c0cSopenharmony_ci            Token::Str("b"),
16997e2e9c0cSopenharmony_ci            Token::SeqEnd,
17007e2e9c0cSopenharmony_ci            Token::Str("d"),
17017e2e9c0cSopenharmony_ci            Token::Str("c"),
17027e2e9c0cSopenharmony_ci            Token::Str("e"),
17037e2e9c0cSopenharmony_ci            Token::U64(2),
17047e2e9c0cSopenharmony_ci            Token::Str("f"),
17057e2e9c0cSopenharmony_ci            Token::U32(3),
17067e2e9c0cSopenharmony_ci            Token::Str("z"),
17077e2e9c0cSopenharmony_ci            Token::U32(4),
17087e2e9c0cSopenharmony_ci            Token::MapEnd,
17097e2e9c0cSopenharmony_ci        ],
17107e2e9c0cSopenharmony_ci    );
17117e2e9c0cSopenharmony_ci
17127e2e9c0cSopenharmony_ci    assert_ser_tokens(
17137e2e9c0cSopenharmony_ci        &Outer {
17147e2e9c0cSopenharmony_ci            y: 0,
17157e2e9c0cSopenharmony_ci            first: First {
17167e2e9c0cSopenharmony_ci                a: 1,
17177e2e9c0cSopenharmony_ci                b: true,
17187e2e9c0cSopenharmony_ci                c: vec!["a".into(), "b".into()],
17197e2e9c0cSopenharmony_ci                d: "c".into(),
17207e2e9c0cSopenharmony_ci                e: Some(2),
17217e2e9c0cSopenharmony_ci            },
17227e2e9c0cSopenharmony_ci            second: Second { f: 3 },
17237e2e9c0cSopenharmony_ci            z: 4,
17247e2e9c0cSopenharmony_ci        },
17257e2e9c0cSopenharmony_ci        &[
17267e2e9c0cSopenharmony_ci            Token::Map { len: None },
17277e2e9c0cSopenharmony_ci            Token::Str("y"),
17287e2e9c0cSopenharmony_ci            Token::U32(0),
17297e2e9c0cSopenharmony_ci            Token::Str("a"),
17307e2e9c0cSopenharmony_ci            Token::U32(1),
17317e2e9c0cSopenharmony_ci            Token::Str("b"),
17327e2e9c0cSopenharmony_ci            Token::Bool(true),
17337e2e9c0cSopenharmony_ci            Token::Str("c"),
17347e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
17357e2e9c0cSopenharmony_ci            Token::Str("a"),
17367e2e9c0cSopenharmony_ci            Token::Str("b"),
17377e2e9c0cSopenharmony_ci            Token::SeqEnd,
17387e2e9c0cSopenharmony_ci            Token::Str("d"),
17397e2e9c0cSopenharmony_ci            Token::Str("c"),
17407e2e9c0cSopenharmony_ci            Token::Str("e"),
17417e2e9c0cSopenharmony_ci            Token::Some,
17427e2e9c0cSopenharmony_ci            Token::U64(2),
17437e2e9c0cSopenharmony_ci            Token::Str("f"),
17447e2e9c0cSopenharmony_ci            Token::U32(3),
17457e2e9c0cSopenharmony_ci            Token::Str("z"),
17467e2e9c0cSopenharmony_ci            Token::U32(4),
17477e2e9c0cSopenharmony_ci            Token::MapEnd,
17487e2e9c0cSopenharmony_ci        ],
17497e2e9c0cSopenharmony_ci    );
17507e2e9c0cSopenharmony_ci}
17517e2e9c0cSopenharmony_ci
17527e2e9c0cSopenharmony_ci#[test]
17537e2e9c0cSopenharmony_cifn test_flatten_map_twice() {
17547e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
17557e2e9c0cSopenharmony_ci    struct Outer {
17567e2e9c0cSopenharmony_ci        #[serde(flatten)]
17577e2e9c0cSopenharmony_ci        first: BTreeMap<String, String>,
17587e2e9c0cSopenharmony_ci        #[serde(flatten)]
17597e2e9c0cSopenharmony_ci        between: Inner,
17607e2e9c0cSopenharmony_ci        #[serde(flatten)]
17617e2e9c0cSopenharmony_ci        second: BTreeMap<String, String>,
17627e2e9c0cSopenharmony_ci    }
17637e2e9c0cSopenharmony_ci
17647e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
17657e2e9c0cSopenharmony_ci    struct Inner {
17667e2e9c0cSopenharmony_ci        y: String,
17677e2e9c0cSopenharmony_ci    }
17687e2e9c0cSopenharmony_ci
17697e2e9c0cSopenharmony_ci    assert_de_tokens(
17707e2e9c0cSopenharmony_ci        &Outer {
17717e2e9c0cSopenharmony_ci            first: {
17727e2e9c0cSopenharmony_ci                let mut first = BTreeMap::new();
17737e2e9c0cSopenharmony_ci                first.insert("x".to_owned(), "X".to_owned());
17747e2e9c0cSopenharmony_ci                first.insert("y".to_owned(), "Y".to_owned());
17757e2e9c0cSopenharmony_ci                first
17767e2e9c0cSopenharmony_ci            },
17777e2e9c0cSopenharmony_ci            between: Inner { y: "Y".to_owned() },
17787e2e9c0cSopenharmony_ci            second: {
17797e2e9c0cSopenharmony_ci                let mut second = BTreeMap::new();
17807e2e9c0cSopenharmony_ci                second.insert("x".to_owned(), "X".to_owned());
17817e2e9c0cSopenharmony_ci                second
17827e2e9c0cSopenharmony_ci            },
17837e2e9c0cSopenharmony_ci        },
17847e2e9c0cSopenharmony_ci        &[
17857e2e9c0cSopenharmony_ci            Token::Map { len: None },
17867e2e9c0cSopenharmony_ci            Token::Str("x"),
17877e2e9c0cSopenharmony_ci            Token::Str("X"),
17887e2e9c0cSopenharmony_ci            Token::Str("y"),
17897e2e9c0cSopenharmony_ci            Token::Str("Y"),
17907e2e9c0cSopenharmony_ci            Token::MapEnd,
17917e2e9c0cSopenharmony_ci        ],
17927e2e9c0cSopenharmony_ci    );
17937e2e9c0cSopenharmony_ci}
17947e2e9c0cSopenharmony_ci
17957e2e9c0cSopenharmony_ci#[test]
17967e2e9c0cSopenharmony_cifn test_flatten_unit() {
17977e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
17987e2e9c0cSopenharmony_ci    struct Response<T> {
17997e2e9c0cSopenharmony_ci        #[serde(flatten)]
18007e2e9c0cSopenharmony_ci        data: T,
18017e2e9c0cSopenharmony_ci        status: usize,
18027e2e9c0cSopenharmony_ci    }
18037e2e9c0cSopenharmony_ci
18047e2e9c0cSopenharmony_ci    assert_tokens(
18057e2e9c0cSopenharmony_ci        &Response {
18067e2e9c0cSopenharmony_ci            data: (),
18077e2e9c0cSopenharmony_ci            status: 0,
18087e2e9c0cSopenharmony_ci        },
18097e2e9c0cSopenharmony_ci        &[
18107e2e9c0cSopenharmony_ci            Token::Map { len: None },
18117e2e9c0cSopenharmony_ci            Token::Str("status"),
18127e2e9c0cSopenharmony_ci            Token::U64(0),
18137e2e9c0cSopenharmony_ci            Token::MapEnd,
18147e2e9c0cSopenharmony_ci        ],
18157e2e9c0cSopenharmony_ci    );
18167e2e9c0cSopenharmony_ci}
18177e2e9c0cSopenharmony_ci
18187e2e9c0cSopenharmony_ci#[test]
18197e2e9c0cSopenharmony_cifn test_flatten_unsupported_type() {
18207e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
18217e2e9c0cSopenharmony_ci    struct Outer {
18227e2e9c0cSopenharmony_ci        outer: String,
18237e2e9c0cSopenharmony_ci        #[serde(flatten)]
18247e2e9c0cSopenharmony_ci        inner: String,
18257e2e9c0cSopenharmony_ci    }
18267e2e9c0cSopenharmony_ci
18277e2e9c0cSopenharmony_ci    assert_ser_tokens_error(
18287e2e9c0cSopenharmony_ci        &Outer {
18297e2e9c0cSopenharmony_ci            outer: "foo".into(),
18307e2e9c0cSopenharmony_ci            inner: "bar".into(),
18317e2e9c0cSopenharmony_ci        },
18327e2e9c0cSopenharmony_ci        &[
18337e2e9c0cSopenharmony_ci            Token::Map { len: None },
18347e2e9c0cSopenharmony_ci            Token::Str("outer"),
18357e2e9c0cSopenharmony_ci            Token::Str("foo"),
18367e2e9c0cSopenharmony_ci        ],
18377e2e9c0cSopenharmony_ci        "can only flatten structs and maps (got a string)",
18387e2e9c0cSopenharmony_ci    );
18397e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Outer>(
18407e2e9c0cSopenharmony_ci        &[
18417e2e9c0cSopenharmony_ci            Token::Map { len: None },
18427e2e9c0cSopenharmony_ci            Token::Str("outer"),
18437e2e9c0cSopenharmony_ci            Token::Str("foo"),
18447e2e9c0cSopenharmony_ci            Token::Str("a"),
18457e2e9c0cSopenharmony_ci            Token::Str("b"),
18467e2e9c0cSopenharmony_ci            Token::MapEnd,
18477e2e9c0cSopenharmony_ci        ],
18487e2e9c0cSopenharmony_ci        "can only flatten structs and maps",
18497e2e9c0cSopenharmony_ci    );
18507e2e9c0cSopenharmony_ci}
18517e2e9c0cSopenharmony_ci
18527e2e9c0cSopenharmony_ci#[test]
18537e2e9c0cSopenharmony_cifn test_non_string_keys() {
18547e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
18557e2e9c0cSopenharmony_ci    struct TestStruct {
18567e2e9c0cSopenharmony_ci        name: String,
18577e2e9c0cSopenharmony_ci        age: u32,
18587e2e9c0cSopenharmony_ci        #[serde(flatten)]
18597e2e9c0cSopenharmony_ci        mapping: HashMap<u32, u32>,
18607e2e9c0cSopenharmony_ci    }
18617e2e9c0cSopenharmony_ci
18627e2e9c0cSopenharmony_ci    let mut mapping = HashMap::new();
18637e2e9c0cSopenharmony_ci    mapping.insert(0, 42);
18647e2e9c0cSopenharmony_ci    assert_tokens(
18657e2e9c0cSopenharmony_ci        &TestStruct {
18667e2e9c0cSopenharmony_ci            name: "peter".into(),
18677e2e9c0cSopenharmony_ci            age: 3,
18687e2e9c0cSopenharmony_ci            mapping,
18697e2e9c0cSopenharmony_ci        },
18707e2e9c0cSopenharmony_ci        &[
18717e2e9c0cSopenharmony_ci            Token::Map { len: None },
18727e2e9c0cSopenharmony_ci            Token::Str("name"),
18737e2e9c0cSopenharmony_ci            Token::Str("peter"),
18747e2e9c0cSopenharmony_ci            Token::Str("age"),
18757e2e9c0cSopenharmony_ci            Token::U32(3),
18767e2e9c0cSopenharmony_ci            Token::U32(0),
18777e2e9c0cSopenharmony_ci            Token::U32(42),
18787e2e9c0cSopenharmony_ci            Token::MapEnd,
18797e2e9c0cSopenharmony_ci        ],
18807e2e9c0cSopenharmony_ci    );
18817e2e9c0cSopenharmony_ci}
18827e2e9c0cSopenharmony_ci
18837e2e9c0cSopenharmony_ci#[test]
18847e2e9c0cSopenharmony_cifn test_lifetime_propagation_for_flatten() {
18857e2e9c0cSopenharmony_ci    #[derive(Deserialize, Serialize, Debug, PartialEq)]
18867e2e9c0cSopenharmony_ci    struct A<T> {
18877e2e9c0cSopenharmony_ci        #[serde(flatten)]
18887e2e9c0cSopenharmony_ci        t: T,
18897e2e9c0cSopenharmony_ci    }
18907e2e9c0cSopenharmony_ci
18917e2e9c0cSopenharmony_ci    #[derive(Deserialize, Serialize, Debug, PartialEq)]
18927e2e9c0cSopenharmony_ci    struct B<'a> {
18937e2e9c0cSopenharmony_ci        #[serde(flatten, borrow)]
18947e2e9c0cSopenharmony_ci        t: HashMap<&'a str, u32>,
18957e2e9c0cSopenharmony_ci    }
18967e2e9c0cSopenharmony_ci
18977e2e9c0cSopenharmony_ci    #[derive(Deserialize, Serialize, Debug, PartialEq)]
18987e2e9c0cSopenharmony_ci    struct C<'a> {
18997e2e9c0cSopenharmony_ci        #[serde(flatten, borrow)]
19007e2e9c0cSopenharmony_ci        t: HashMap<&'a [u8], u32>,
19017e2e9c0cSopenharmony_ci    }
19027e2e9c0cSopenharmony_ci
19037e2e9c0cSopenharmony_ci    let mut owned_map = HashMap::new();
19047e2e9c0cSopenharmony_ci    owned_map.insert("x".to_string(), 42u32);
19057e2e9c0cSopenharmony_ci    assert_tokens(
19067e2e9c0cSopenharmony_ci        &A { t: owned_map },
19077e2e9c0cSopenharmony_ci        &[
19087e2e9c0cSopenharmony_ci            Token::Map { len: None },
19097e2e9c0cSopenharmony_ci            Token::Str("x"),
19107e2e9c0cSopenharmony_ci            Token::U32(42),
19117e2e9c0cSopenharmony_ci            Token::MapEnd,
19127e2e9c0cSopenharmony_ci        ],
19137e2e9c0cSopenharmony_ci    );
19147e2e9c0cSopenharmony_ci
19157e2e9c0cSopenharmony_ci    let mut borrowed_map = HashMap::new();
19167e2e9c0cSopenharmony_ci    borrowed_map.insert("x", 42u32);
19177e2e9c0cSopenharmony_ci    assert_ser_tokens(
19187e2e9c0cSopenharmony_ci        &B {
19197e2e9c0cSopenharmony_ci            t: borrowed_map.clone(),
19207e2e9c0cSopenharmony_ci        },
19217e2e9c0cSopenharmony_ci        &[
19227e2e9c0cSopenharmony_ci            Token::Map { len: None },
19237e2e9c0cSopenharmony_ci            Token::BorrowedStr("x"),
19247e2e9c0cSopenharmony_ci            Token::U32(42),
19257e2e9c0cSopenharmony_ci            Token::MapEnd,
19267e2e9c0cSopenharmony_ci        ],
19277e2e9c0cSopenharmony_ci    );
19287e2e9c0cSopenharmony_ci
19297e2e9c0cSopenharmony_ci    assert_de_tokens(
19307e2e9c0cSopenharmony_ci        &B { t: borrowed_map },
19317e2e9c0cSopenharmony_ci        &[
19327e2e9c0cSopenharmony_ci            Token::Map { len: None },
19337e2e9c0cSopenharmony_ci            Token::BorrowedStr("x"),
19347e2e9c0cSopenharmony_ci            Token::U32(42),
19357e2e9c0cSopenharmony_ci            Token::MapEnd,
19367e2e9c0cSopenharmony_ci        ],
19377e2e9c0cSopenharmony_ci    );
19387e2e9c0cSopenharmony_ci
19397e2e9c0cSopenharmony_ci    let mut borrowed_map = HashMap::new();
19407e2e9c0cSopenharmony_ci    borrowed_map.insert(&b"x"[..], 42u32);
19417e2e9c0cSopenharmony_ci    assert_ser_tokens(
19427e2e9c0cSopenharmony_ci        &C {
19437e2e9c0cSopenharmony_ci            t: borrowed_map.clone(),
19447e2e9c0cSopenharmony_ci        },
19457e2e9c0cSopenharmony_ci        &[
19467e2e9c0cSopenharmony_ci            Token::Map { len: None },
19477e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
19487e2e9c0cSopenharmony_ci            Token::U8(120),
19497e2e9c0cSopenharmony_ci            Token::SeqEnd,
19507e2e9c0cSopenharmony_ci            Token::U32(42),
19517e2e9c0cSopenharmony_ci            Token::MapEnd,
19527e2e9c0cSopenharmony_ci        ],
19537e2e9c0cSopenharmony_ci    );
19547e2e9c0cSopenharmony_ci
19557e2e9c0cSopenharmony_ci    assert_de_tokens(
19567e2e9c0cSopenharmony_ci        &C { t: borrowed_map },
19577e2e9c0cSopenharmony_ci        &[
19587e2e9c0cSopenharmony_ci            Token::Map { len: None },
19597e2e9c0cSopenharmony_ci            Token::BorrowedBytes(b"x"),
19607e2e9c0cSopenharmony_ci            Token::U32(42),
19617e2e9c0cSopenharmony_ci            Token::MapEnd,
19627e2e9c0cSopenharmony_ci        ],
19637e2e9c0cSopenharmony_ci    );
19647e2e9c0cSopenharmony_ci}
19657e2e9c0cSopenharmony_ci
19667e2e9c0cSopenharmony_ci#[test]
19677e2e9c0cSopenharmony_cifn test_externally_tagged_enum_containing_flatten() {
19687e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
19697e2e9c0cSopenharmony_ci    enum Data {
19707e2e9c0cSopenharmony_ci        A {
19717e2e9c0cSopenharmony_ci            a: i32,
19727e2e9c0cSopenharmony_ci            #[serde(flatten)]
19737e2e9c0cSopenharmony_ci            flat: Flat,
19747e2e9c0cSopenharmony_ci        },
19757e2e9c0cSopenharmony_ci    }
19767e2e9c0cSopenharmony_ci
19777e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
19787e2e9c0cSopenharmony_ci    struct Flat {
19797e2e9c0cSopenharmony_ci        b: i32,
19807e2e9c0cSopenharmony_ci    }
19817e2e9c0cSopenharmony_ci
19827e2e9c0cSopenharmony_ci    let data = Data::A {
19837e2e9c0cSopenharmony_ci        a: 0,
19847e2e9c0cSopenharmony_ci        flat: Flat { b: 0 },
19857e2e9c0cSopenharmony_ci    };
19867e2e9c0cSopenharmony_ci
19877e2e9c0cSopenharmony_ci    assert_tokens(
19887e2e9c0cSopenharmony_ci        &data,
19897e2e9c0cSopenharmony_ci        &[
19907e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
19917e2e9c0cSopenharmony_ci                name: "Data",
19927e2e9c0cSopenharmony_ci                variant: "A",
19937e2e9c0cSopenharmony_ci            },
19947e2e9c0cSopenharmony_ci            Token::Map { len: None },
19957e2e9c0cSopenharmony_ci            Token::Str("a"),
19967e2e9c0cSopenharmony_ci            Token::I32(0),
19977e2e9c0cSopenharmony_ci            Token::Str("b"),
19987e2e9c0cSopenharmony_ci            Token::I32(0),
19997e2e9c0cSopenharmony_ci            Token::MapEnd,
20007e2e9c0cSopenharmony_ci        ],
20017e2e9c0cSopenharmony_ci    );
20027e2e9c0cSopenharmony_ci}
20037e2e9c0cSopenharmony_ci
20047e2e9c0cSopenharmony_ci#[test]
20057e2e9c0cSopenharmony_cifn test_internally_tagged_enum_with_skipped_conflict() {
20067e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
20077e2e9c0cSopenharmony_ci    #[serde(tag = "t")]
20087e2e9c0cSopenharmony_ci    enum Data {
20097e2e9c0cSopenharmony_ci        A,
20107e2e9c0cSopenharmony_ci        #[serde(skip)]
20117e2e9c0cSopenharmony_ci        #[allow(dead_code)]
20127e2e9c0cSopenharmony_ci        B {
20137e2e9c0cSopenharmony_ci            t: String,
20147e2e9c0cSopenharmony_ci        },
20157e2e9c0cSopenharmony_ci        C {
20167e2e9c0cSopenharmony_ci            #[serde(default, skip)]
20177e2e9c0cSopenharmony_ci            t: String,
20187e2e9c0cSopenharmony_ci        },
20197e2e9c0cSopenharmony_ci    }
20207e2e9c0cSopenharmony_ci
20217e2e9c0cSopenharmony_ci    let data = Data::C { t: String::new() };
20227e2e9c0cSopenharmony_ci
20237e2e9c0cSopenharmony_ci    assert_tokens(
20247e2e9c0cSopenharmony_ci        &data,
20257e2e9c0cSopenharmony_ci        &[
20267e2e9c0cSopenharmony_ci            Token::Struct {
20277e2e9c0cSopenharmony_ci                name: "Data",
20287e2e9c0cSopenharmony_ci                len: 1,
20297e2e9c0cSopenharmony_ci            },
20307e2e9c0cSopenharmony_ci            Token::Str("t"),
20317e2e9c0cSopenharmony_ci            Token::Str("C"),
20327e2e9c0cSopenharmony_ci            Token::StructEnd,
20337e2e9c0cSopenharmony_ci        ],
20347e2e9c0cSopenharmony_ci    );
20357e2e9c0cSopenharmony_ci}
20367e2e9c0cSopenharmony_ci
20377e2e9c0cSopenharmony_ci#[test]
20387e2e9c0cSopenharmony_cifn test_internally_tagged_enum_containing_flatten() {
20397e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
20407e2e9c0cSopenharmony_ci    #[serde(tag = "t")]
20417e2e9c0cSopenharmony_ci    enum Data {
20427e2e9c0cSopenharmony_ci        A {
20437e2e9c0cSopenharmony_ci            a: i32,
20447e2e9c0cSopenharmony_ci            #[serde(flatten)]
20457e2e9c0cSopenharmony_ci            flat: Flat,
20467e2e9c0cSopenharmony_ci        },
20477e2e9c0cSopenharmony_ci    }
20487e2e9c0cSopenharmony_ci
20497e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
20507e2e9c0cSopenharmony_ci    struct Flat {
20517e2e9c0cSopenharmony_ci        b: i32,
20527e2e9c0cSopenharmony_ci    }
20537e2e9c0cSopenharmony_ci
20547e2e9c0cSopenharmony_ci    let data = Data::A {
20557e2e9c0cSopenharmony_ci        a: 0,
20567e2e9c0cSopenharmony_ci        flat: Flat { b: 0 },
20577e2e9c0cSopenharmony_ci    };
20587e2e9c0cSopenharmony_ci
20597e2e9c0cSopenharmony_ci    assert_tokens(
20607e2e9c0cSopenharmony_ci        &data,
20617e2e9c0cSopenharmony_ci        &[
20627e2e9c0cSopenharmony_ci            Token::Map { len: None },
20637e2e9c0cSopenharmony_ci            Token::Str("t"),
20647e2e9c0cSopenharmony_ci            Token::Str("A"),
20657e2e9c0cSopenharmony_ci            Token::Str("a"),
20667e2e9c0cSopenharmony_ci            Token::I32(0),
20677e2e9c0cSopenharmony_ci            Token::Str("b"),
20687e2e9c0cSopenharmony_ci            Token::I32(0),
20697e2e9c0cSopenharmony_ci            Token::MapEnd,
20707e2e9c0cSopenharmony_ci        ],
20717e2e9c0cSopenharmony_ci    );
20727e2e9c0cSopenharmony_ci}
20737e2e9c0cSopenharmony_ci
20747e2e9c0cSopenharmony_ci#[test]
20757e2e9c0cSopenharmony_cifn test_internally_tagged_enum_new_type_with_unit() {
20767e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
20777e2e9c0cSopenharmony_ci    #[serde(tag = "t")]
20787e2e9c0cSopenharmony_ci    enum Data {
20797e2e9c0cSopenharmony_ci        A(()),
20807e2e9c0cSopenharmony_ci    }
20817e2e9c0cSopenharmony_ci
20827e2e9c0cSopenharmony_ci    assert_tokens(
20837e2e9c0cSopenharmony_ci        &Data::A(()),
20847e2e9c0cSopenharmony_ci        &[
20857e2e9c0cSopenharmony_ci            Token::Map { len: Some(1) },
20867e2e9c0cSopenharmony_ci            Token::Str("t"),
20877e2e9c0cSopenharmony_ci            Token::Str("A"),
20887e2e9c0cSopenharmony_ci            Token::MapEnd,
20897e2e9c0cSopenharmony_ci        ],
20907e2e9c0cSopenharmony_ci    );
20917e2e9c0cSopenharmony_ci}
20927e2e9c0cSopenharmony_ci
20937e2e9c0cSopenharmony_ci#[test]
20947e2e9c0cSopenharmony_cifn test_adjacently_tagged_enum_bytes() {
20957e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
20967e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c")]
20977e2e9c0cSopenharmony_ci    enum Data {
20987e2e9c0cSopenharmony_ci        A { a: i32 },
20997e2e9c0cSopenharmony_ci    }
21007e2e9c0cSopenharmony_ci
21017e2e9c0cSopenharmony_ci    let data = Data::A { a: 0 };
21027e2e9c0cSopenharmony_ci
21037e2e9c0cSopenharmony_ci    assert_tokens(
21047e2e9c0cSopenharmony_ci        &data,
21057e2e9c0cSopenharmony_ci        &[
21067e2e9c0cSopenharmony_ci            Token::Struct {
21077e2e9c0cSopenharmony_ci                name: "Data",
21087e2e9c0cSopenharmony_ci                len: 2,
21097e2e9c0cSopenharmony_ci            },
21107e2e9c0cSopenharmony_ci            Token::Str("t"),
21117e2e9c0cSopenharmony_ci            Token::UnitVariant {
21127e2e9c0cSopenharmony_ci                name: "Data",
21137e2e9c0cSopenharmony_ci                variant: "A",
21147e2e9c0cSopenharmony_ci            },
21157e2e9c0cSopenharmony_ci            Token::Str("c"),
21167e2e9c0cSopenharmony_ci            Token::Struct { name: "A", len: 1 },
21177e2e9c0cSopenharmony_ci            Token::Str("a"),
21187e2e9c0cSopenharmony_ci            Token::I32(0),
21197e2e9c0cSopenharmony_ci            Token::StructEnd,
21207e2e9c0cSopenharmony_ci            Token::StructEnd,
21217e2e9c0cSopenharmony_ci        ],
21227e2e9c0cSopenharmony_ci    );
21237e2e9c0cSopenharmony_ci
21247e2e9c0cSopenharmony_ci    assert_de_tokens(
21257e2e9c0cSopenharmony_ci        &data,
21267e2e9c0cSopenharmony_ci        &[
21277e2e9c0cSopenharmony_ci            Token::Struct {
21287e2e9c0cSopenharmony_ci                name: "Data",
21297e2e9c0cSopenharmony_ci                len: 2,
21307e2e9c0cSopenharmony_ci            },
21317e2e9c0cSopenharmony_ci            Token::Bytes(b"t"),
21327e2e9c0cSopenharmony_ci            Token::UnitVariant {
21337e2e9c0cSopenharmony_ci                name: "Data",
21347e2e9c0cSopenharmony_ci                variant: "A",
21357e2e9c0cSopenharmony_ci            },
21367e2e9c0cSopenharmony_ci            Token::Bytes(b"c"),
21377e2e9c0cSopenharmony_ci            Token::Struct { name: "A", len: 1 },
21387e2e9c0cSopenharmony_ci            Token::Str("a"),
21397e2e9c0cSopenharmony_ci            Token::I32(0),
21407e2e9c0cSopenharmony_ci            Token::StructEnd,
21417e2e9c0cSopenharmony_ci            Token::StructEnd,
21427e2e9c0cSopenharmony_ci        ],
21437e2e9c0cSopenharmony_ci    );
21447e2e9c0cSopenharmony_ci}
21457e2e9c0cSopenharmony_ci
21467e2e9c0cSopenharmony_ci#[test]
21477e2e9c0cSopenharmony_cifn test_adjacently_tagged_enum_containing_flatten() {
21487e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
21497e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c")]
21507e2e9c0cSopenharmony_ci    enum Data {
21517e2e9c0cSopenharmony_ci        A {
21527e2e9c0cSopenharmony_ci            a: i32,
21537e2e9c0cSopenharmony_ci            #[serde(flatten)]
21547e2e9c0cSopenharmony_ci            flat: Flat,
21557e2e9c0cSopenharmony_ci        },
21567e2e9c0cSopenharmony_ci    }
21577e2e9c0cSopenharmony_ci
21587e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
21597e2e9c0cSopenharmony_ci    struct Flat {
21607e2e9c0cSopenharmony_ci        b: i32,
21617e2e9c0cSopenharmony_ci    }
21627e2e9c0cSopenharmony_ci
21637e2e9c0cSopenharmony_ci    let data = Data::A {
21647e2e9c0cSopenharmony_ci        a: 0,
21657e2e9c0cSopenharmony_ci        flat: Flat { b: 0 },
21667e2e9c0cSopenharmony_ci    };
21677e2e9c0cSopenharmony_ci
21687e2e9c0cSopenharmony_ci    assert_tokens(
21697e2e9c0cSopenharmony_ci        &data,
21707e2e9c0cSopenharmony_ci        &[
21717e2e9c0cSopenharmony_ci            Token::Struct {
21727e2e9c0cSopenharmony_ci                name: "Data",
21737e2e9c0cSopenharmony_ci                len: 2,
21747e2e9c0cSopenharmony_ci            },
21757e2e9c0cSopenharmony_ci            Token::Str("t"),
21767e2e9c0cSopenharmony_ci            Token::UnitVariant {
21777e2e9c0cSopenharmony_ci                name: "Data",
21787e2e9c0cSopenharmony_ci                variant: "A",
21797e2e9c0cSopenharmony_ci            },
21807e2e9c0cSopenharmony_ci            Token::Str("c"),
21817e2e9c0cSopenharmony_ci            Token::Map { len: None },
21827e2e9c0cSopenharmony_ci            Token::Str("a"),
21837e2e9c0cSopenharmony_ci            Token::I32(0),
21847e2e9c0cSopenharmony_ci            Token::Str("b"),
21857e2e9c0cSopenharmony_ci            Token::I32(0),
21867e2e9c0cSopenharmony_ci            Token::MapEnd,
21877e2e9c0cSopenharmony_ci            Token::StructEnd,
21887e2e9c0cSopenharmony_ci        ],
21897e2e9c0cSopenharmony_ci    );
21907e2e9c0cSopenharmony_ci}
21917e2e9c0cSopenharmony_ci
21927e2e9c0cSopenharmony_ci#[test]
21937e2e9c0cSopenharmony_cifn test_untagged_enum_containing_flatten() {
21947e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
21957e2e9c0cSopenharmony_ci    #[serde(untagged)]
21967e2e9c0cSopenharmony_ci    enum Data {
21977e2e9c0cSopenharmony_ci        A {
21987e2e9c0cSopenharmony_ci            a: i32,
21997e2e9c0cSopenharmony_ci            #[serde(flatten)]
22007e2e9c0cSopenharmony_ci            flat: Flat,
22017e2e9c0cSopenharmony_ci        },
22027e2e9c0cSopenharmony_ci    }
22037e2e9c0cSopenharmony_ci
22047e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
22057e2e9c0cSopenharmony_ci    struct Flat {
22067e2e9c0cSopenharmony_ci        b: i32,
22077e2e9c0cSopenharmony_ci    }
22087e2e9c0cSopenharmony_ci
22097e2e9c0cSopenharmony_ci    let data = Data::A {
22107e2e9c0cSopenharmony_ci        a: 0,
22117e2e9c0cSopenharmony_ci        flat: Flat { b: 0 },
22127e2e9c0cSopenharmony_ci    };
22137e2e9c0cSopenharmony_ci
22147e2e9c0cSopenharmony_ci    assert_tokens(
22157e2e9c0cSopenharmony_ci        &data,
22167e2e9c0cSopenharmony_ci        &[
22177e2e9c0cSopenharmony_ci            Token::Map { len: None },
22187e2e9c0cSopenharmony_ci            Token::Str("a"),
22197e2e9c0cSopenharmony_ci            Token::I32(0),
22207e2e9c0cSopenharmony_ci            Token::Str("b"),
22217e2e9c0cSopenharmony_ci            Token::I32(0),
22227e2e9c0cSopenharmony_ci            Token::MapEnd,
22237e2e9c0cSopenharmony_ci        ],
22247e2e9c0cSopenharmony_ci    );
22257e2e9c0cSopenharmony_ci}
22267e2e9c0cSopenharmony_ci
22277e2e9c0cSopenharmony_ci#[test]
22287e2e9c0cSopenharmony_cifn test_partially_untagged_enum() {
22297e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
22307e2e9c0cSopenharmony_ci    enum Exp {
22317e2e9c0cSopenharmony_ci        Lambda(u32, Box<Exp>),
22327e2e9c0cSopenharmony_ci        #[serde(untagged)]
22337e2e9c0cSopenharmony_ci        App(Box<Exp>, Box<Exp>),
22347e2e9c0cSopenharmony_ci        #[serde(untagged)]
22357e2e9c0cSopenharmony_ci        Var(u32),
22367e2e9c0cSopenharmony_ci    }
22377e2e9c0cSopenharmony_ci    use Exp::*;
22387e2e9c0cSopenharmony_ci
22397e2e9c0cSopenharmony_ci    let data = Lambda(0, Box::new(App(Box::new(Var(0)), Box::new(Var(0)))));
22407e2e9c0cSopenharmony_ci    assert_tokens(
22417e2e9c0cSopenharmony_ci        &data,
22427e2e9c0cSopenharmony_ci        &[
22437e2e9c0cSopenharmony_ci            Token::TupleVariant {
22447e2e9c0cSopenharmony_ci                name: "Exp",
22457e2e9c0cSopenharmony_ci                variant: "Lambda",
22467e2e9c0cSopenharmony_ci                len: 2,
22477e2e9c0cSopenharmony_ci            },
22487e2e9c0cSopenharmony_ci            Token::U32(0),
22497e2e9c0cSopenharmony_ci            Token::Tuple { len: 2 },
22507e2e9c0cSopenharmony_ci            Token::U32(0),
22517e2e9c0cSopenharmony_ci            Token::U32(0),
22527e2e9c0cSopenharmony_ci            Token::TupleEnd,
22537e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
22547e2e9c0cSopenharmony_ci        ],
22557e2e9c0cSopenharmony_ci    );
22567e2e9c0cSopenharmony_ci}
22577e2e9c0cSopenharmony_ci
22587e2e9c0cSopenharmony_ci#[test]
22597e2e9c0cSopenharmony_cifn test_partially_untagged_enum_generic() {
22607e2e9c0cSopenharmony_ci    trait Trait<T> {
22617e2e9c0cSopenharmony_ci        type Assoc;
22627e2e9c0cSopenharmony_ci        type Assoc2;
22637e2e9c0cSopenharmony_ci    }
22647e2e9c0cSopenharmony_ci
22657e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
22667e2e9c0cSopenharmony_ci    enum E<A, B, C>
22677e2e9c0cSopenharmony_ci    where
22687e2e9c0cSopenharmony_ci        A: Trait<C, Assoc2 = B>,
22697e2e9c0cSopenharmony_ci    {
22707e2e9c0cSopenharmony_ci        A(A::Assoc),
22717e2e9c0cSopenharmony_ci        #[serde(untagged)]
22727e2e9c0cSopenharmony_ci        B(A::Assoc2),
22737e2e9c0cSopenharmony_ci    }
22747e2e9c0cSopenharmony_ci
22757e2e9c0cSopenharmony_ci    impl<T> Trait<T> for () {
22767e2e9c0cSopenharmony_ci        type Assoc = T;
22777e2e9c0cSopenharmony_ci        type Assoc2 = bool;
22787e2e9c0cSopenharmony_ci    }
22797e2e9c0cSopenharmony_ci
22807e2e9c0cSopenharmony_ci    type MyE = E<(), bool, u32>;
22817e2e9c0cSopenharmony_ci    use E::*;
22827e2e9c0cSopenharmony_ci
22837e2e9c0cSopenharmony_ci    assert_tokens::<MyE>(&B(true), &[Token::Bool(true)]);
22847e2e9c0cSopenharmony_ci
22857e2e9c0cSopenharmony_ci    assert_tokens::<MyE>(
22867e2e9c0cSopenharmony_ci        &A(5),
22877e2e9c0cSopenharmony_ci        &[
22887e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
22897e2e9c0cSopenharmony_ci                name: "E",
22907e2e9c0cSopenharmony_ci                variant: "A",
22917e2e9c0cSopenharmony_ci            },
22927e2e9c0cSopenharmony_ci            Token::U32(5),
22937e2e9c0cSopenharmony_ci        ],
22947e2e9c0cSopenharmony_ci    );
22957e2e9c0cSopenharmony_ci}
22967e2e9c0cSopenharmony_ci
22977e2e9c0cSopenharmony_ci#[test]
22987e2e9c0cSopenharmony_cifn test_partially_untagged_enum_desugared() {
22997e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
23007e2e9c0cSopenharmony_ci    enum Test {
23017e2e9c0cSopenharmony_ci        A(u32, u32),
23027e2e9c0cSopenharmony_ci        B(u32),
23037e2e9c0cSopenharmony_ci        #[serde(untagged)]
23047e2e9c0cSopenharmony_ci        C(u32),
23057e2e9c0cSopenharmony_ci        #[serde(untagged)]
23067e2e9c0cSopenharmony_ci        D(u32, u32),
23077e2e9c0cSopenharmony_ci    }
23087e2e9c0cSopenharmony_ci    use Test::*;
23097e2e9c0cSopenharmony_ci
23107e2e9c0cSopenharmony_ci    mod desugared {
23117e2e9c0cSopenharmony_ci        use super::*;
23127e2e9c0cSopenharmony_ci        #[derive(Serialize, Deserialize, PartialEq, Debug)]
23137e2e9c0cSopenharmony_ci        pub(super) enum Test {
23147e2e9c0cSopenharmony_ci            A(u32, u32),
23157e2e9c0cSopenharmony_ci            B(u32),
23167e2e9c0cSopenharmony_ci        }
23177e2e9c0cSopenharmony_ci    }
23187e2e9c0cSopenharmony_ci    use desugared::Test as TestTagged;
23197e2e9c0cSopenharmony_ci
23207e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
23217e2e9c0cSopenharmony_ci    #[serde(untagged)]
23227e2e9c0cSopenharmony_ci    enum TestUntagged {
23237e2e9c0cSopenharmony_ci        Tagged(TestTagged),
23247e2e9c0cSopenharmony_ci        C(u32),
23257e2e9c0cSopenharmony_ci        D(u32, u32),
23267e2e9c0cSopenharmony_ci    }
23277e2e9c0cSopenharmony_ci
23287e2e9c0cSopenharmony_ci    impl From<Test> for TestUntagged {
23297e2e9c0cSopenharmony_ci        fn from(test: Test) -> Self {
23307e2e9c0cSopenharmony_ci            match test {
23317e2e9c0cSopenharmony_ci                A(x, y) => TestUntagged::Tagged(TestTagged::A(x, y)),
23327e2e9c0cSopenharmony_ci                B(x) => TestUntagged::Tagged(TestTagged::B(x)),
23337e2e9c0cSopenharmony_ci                C(x) => TestUntagged::C(x),
23347e2e9c0cSopenharmony_ci                D(x, y) => TestUntagged::D(x, y),
23357e2e9c0cSopenharmony_ci            }
23367e2e9c0cSopenharmony_ci        }
23377e2e9c0cSopenharmony_ci    }
23387e2e9c0cSopenharmony_ci
23397e2e9c0cSopenharmony_ci    fn assert_tokens_desugared(value: Test, tokens: &[Token]) {
23407e2e9c0cSopenharmony_ci        assert_tokens(&value, tokens);
23417e2e9c0cSopenharmony_ci        let desugared: TestUntagged = value.into();
23427e2e9c0cSopenharmony_ci        assert_tokens(&desugared, tokens);
23437e2e9c0cSopenharmony_ci    }
23447e2e9c0cSopenharmony_ci
23457e2e9c0cSopenharmony_ci    assert_tokens_desugared(
23467e2e9c0cSopenharmony_ci        A(0, 1),
23477e2e9c0cSopenharmony_ci        &[
23487e2e9c0cSopenharmony_ci            Token::TupleVariant {
23497e2e9c0cSopenharmony_ci                name: "Test",
23507e2e9c0cSopenharmony_ci                variant: "A",
23517e2e9c0cSopenharmony_ci                len: 2,
23527e2e9c0cSopenharmony_ci            },
23537e2e9c0cSopenharmony_ci            Token::U32(0),
23547e2e9c0cSopenharmony_ci            Token::U32(1),
23557e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
23567e2e9c0cSopenharmony_ci        ],
23577e2e9c0cSopenharmony_ci    );
23587e2e9c0cSopenharmony_ci
23597e2e9c0cSopenharmony_ci    assert_tokens_desugared(
23607e2e9c0cSopenharmony_ci        B(1),
23617e2e9c0cSopenharmony_ci        &[
23627e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
23637e2e9c0cSopenharmony_ci                name: "Test",
23647e2e9c0cSopenharmony_ci                variant: "B",
23657e2e9c0cSopenharmony_ci            },
23667e2e9c0cSopenharmony_ci            Token::U32(1),
23677e2e9c0cSopenharmony_ci        ],
23687e2e9c0cSopenharmony_ci    );
23697e2e9c0cSopenharmony_ci
23707e2e9c0cSopenharmony_ci    assert_tokens_desugared(C(2), &[Token::U32(2)]);
23717e2e9c0cSopenharmony_ci
23727e2e9c0cSopenharmony_ci    assert_tokens_desugared(
23737e2e9c0cSopenharmony_ci        D(3, 5),
23747e2e9c0cSopenharmony_ci        &[
23757e2e9c0cSopenharmony_ci            Token::Tuple { len: 2 },
23767e2e9c0cSopenharmony_ci            Token::U32(3),
23777e2e9c0cSopenharmony_ci            Token::U32(5),
23787e2e9c0cSopenharmony_ci            Token::TupleEnd,
23797e2e9c0cSopenharmony_ci        ],
23807e2e9c0cSopenharmony_ci    );
23817e2e9c0cSopenharmony_ci}
23827e2e9c0cSopenharmony_ci
23837e2e9c0cSopenharmony_ci#[test]
23847e2e9c0cSopenharmony_cifn test_partially_untagged_internally_tagged_enum() {
23857e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
23867e2e9c0cSopenharmony_ci    #[serde(tag = "t")]
23877e2e9c0cSopenharmony_ci    enum Data {
23887e2e9c0cSopenharmony_ci        A,
23897e2e9c0cSopenharmony_ci        B,
23907e2e9c0cSopenharmony_ci        #[serde(untagged)]
23917e2e9c0cSopenharmony_ci        Var(u32),
23927e2e9c0cSopenharmony_ci    }
23937e2e9c0cSopenharmony_ci
23947e2e9c0cSopenharmony_ci    let data = Data::A;
23957e2e9c0cSopenharmony_ci
23967e2e9c0cSopenharmony_ci    assert_de_tokens(
23977e2e9c0cSopenharmony_ci        &data,
23987e2e9c0cSopenharmony_ci        &[
23997e2e9c0cSopenharmony_ci            Token::Map { len: None },
24007e2e9c0cSopenharmony_ci            Token::Str("t"),
24017e2e9c0cSopenharmony_ci            Token::Str("A"),
24027e2e9c0cSopenharmony_ci            Token::MapEnd,
24037e2e9c0cSopenharmony_ci        ],
24047e2e9c0cSopenharmony_ci    );
24057e2e9c0cSopenharmony_ci
24067e2e9c0cSopenharmony_ci    let data = Data::Var(42);
24077e2e9c0cSopenharmony_ci
24087e2e9c0cSopenharmony_ci    assert_de_tokens(&data, &[Token::U32(42)]);
24097e2e9c0cSopenharmony_ci
24107e2e9c0cSopenharmony_ci    // TODO test error output
24117e2e9c0cSopenharmony_ci}
24127e2e9c0cSopenharmony_ci
24137e2e9c0cSopenharmony_ci#[test]
24147e2e9c0cSopenharmony_cifn test_partially_untagged_adjacently_tagged_enum() {
24157e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
24167e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c")]
24177e2e9c0cSopenharmony_ci    enum Data {
24187e2e9c0cSopenharmony_ci        A(u32),
24197e2e9c0cSopenharmony_ci        B,
24207e2e9c0cSopenharmony_ci        #[serde(untagged)]
24217e2e9c0cSopenharmony_ci        Var(u32),
24227e2e9c0cSopenharmony_ci    }
24237e2e9c0cSopenharmony_ci
24247e2e9c0cSopenharmony_ci    let data = Data::A(7);
24257e2e9c0cSopenharmony_ci
24267e2e9c0cSopenharmony_ci    assert_de_tokens(
24277e2e9c0cSopenharmony_ci        &data,
24287e2e9c0cSopenharmony_ci        &[
24297e2e9c0cSopenharmony_ci            Token::Map { len: None },
24307e2e9c0cSopenharmony_ci            Token::Str("t"),
24317e2e9c0cSopenharmony_ci            Token::Str("A"),
24327e2e9c0cSopenharmony_ci            Token::Str("c"),
24337e2e9c0cSopenharmony_ci            Token::U32(7),
24347e2e9c0cSopenharmony_ci            Token::MapEnd,
24357e2e9c0cSopenharmony_ci        ],
24367e2e9c0cSopenharmony_ci    );
24377e2e9c0cSopenharmony_ci
24387e2e9c0cSopenharmony_ci    let data = Data::Var(42);
24397e2e9c0cSopenharmony_ci
24407e2e9c0cSopenharmony_ci    assert_de_tokens(&data, &[Token::U32(42)]);
24417e2e9c0cSopenharmony_ci
24427e2e9c0cSopenharmony_ci    // TODO test error output
24437e2e9c0cSopenharmony_ci}
24447e2e9c0cSopenharmony_ci
24457e2e9c0cSopenharmony_ci#[test]
24467e2e9c0cSopenharmony_cifn test_flatten_option() {
24477e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
24487e2e9c0cSopenharmony_ci    struct Outer {
24497e2e9c0cSopenharmony_ci        #[serde(flatten)]
24507e2e9c0cSopenharmony_ci        inner1: Option<Inner1>,
24517e2e9c0cSopenharmony_ci        #[serde(flatten)]
24527e2e9c0cSopenharmony_ci        inner2: Option<Inner2>,
24537e2e9c0cSopenharmony_ci    }
24547e2e9c0cSopenharmony_ci
24557e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
24567e2e9c0cSopenharmony_ci    struct Inner1 {
24577e2e9c0cSopenharmony_ci        inner1: i32,
24587e2e9c0cSopenharmony_ci    }
24597e2e9c0cSopenharmony_ci
24607e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
24617e2e9c0cSopenharmony_ci    struct Inner2 {
24627e2e9c0cSopenharmony_ci        inner2: i32,
24637e2e9c0cSopenharmony_ci    }
24647e2e9c0cSopenharmony_ci
24657e2e9c0cSopenharmony_ci    assert_tokens(
24667e2e9c0cSopenharmony_ci        &Outer {
24677e2e9c0cSopenharmony_ci            inner1: Some(Inner1 { inner1: 1 }),
24687e2e9c0cSopenharmony_ci            inner2: Some(Inner2 { inner2: 2 }),
24697e2e9c0cSopenharmony_ci        },
24707e2e9c0cSopenharmony_ci        &[
24717e2e9c0cSopenharmony_ci            Token::Map { len: None },
24727e2e9c0cSopenharmony_ci            Token::Str("inner1"),
24737e2e9c0cSopenharmony_ci            Token::I32(1),
24747e2e9c0cSopenharmony_ci            Token::Str("inner2"),
24757e2e9c0cSopenharmony_ci            Token::I32(2),
24767e2e9c0cSopenharmony_ci            Token::MapEnd,
24777e2e9c0cSopenharmony_ci        ],
24787e2e9c0cSopenharmony_ci    );
24797e2e9c0cSopenharmony_ci
24807e2e9c0cSopenharmony_ci    assert_tokens(
24817e2e9c0cSopenharmony_ci        &Outer {
24827e2e9c0cSopenharmony_ci            inner1: Some(Inner1 { inner1: 1 }),
24837e2e9c0cSopenharmony_ci            inner2: None,
24847e2e9c0cSopenharmony_ci        },
24857e2e9c0cSopenharmony_ci        &[
24867e2e9c0cSopenharmony_ci            Token::Map { len: None },
24877e2e9c0cSopenharmony_ci            Token::Str("inner1"),
24887e2e9c0cSopenharmony_ci            Token::I32(1),
24897e2e9c0cSopenharmony_ci            Token::MapEnd,
24907e2e9c0cSopenharmony_ci        ],
24917e2e9c0cSopenharmony_ci    );
24927e2e9c0cSopenharmony_ci
24937e2e9c0cSopenharmony_ci    assert_tokens(
24947e2e9c0cSopenharmony_ci        &Outer {
24957e2e9c0cSopenharmony_ci            inner1: None,
24967e2e9c0cSopenharmony_ci            inner2: Some(Inner2 { inner2: 2 }),
24977e2e9c0cSopenharmony_ci        },
24987e2e9c0cSopenharmony_ci        &[
24997e2e9c0cSopenharmony_ci            Token::Map { len: None },
25007e2e9c0cSopenharmony_ci            Token::Str("inner2"),
25017e2e9c0cSopenharmony_ci            Token::I32(2),
25027e2e9c0cSopenharmony_ci            Token::MapEnd,
25037e2e9c0cSopenharmony_ci        ],
25047e2e9c0cSopenharmony_ci    );
25057e2e9c0cSopenharmony_ci
25067e2e9c0cSopenharmony_ci    assert_tokens(
25077e2e9c0cSopenharmony_ci        &Outer {
25087e2e9c0cSopenharmony_ci            inner1: None,
25097e2e9c0cSopenharmony_ci            inner2: None,
25107e2e9c0cSopenharmony_ci        },
25117e2e9c0cSopenharmony_ci        &[Token::Map { len: None }, Token::MapEnd],
25127e2e9c0cSopenharmony_ci    );
25137e2e9c0cSopenharmony_ci}
25147e2e9c0cSopenharmony_ci
25157e2e9c0cSopenharmony_ci#[test]
25167e2e9c0cSopenharmony_cifn test_flatten_ignored_any() {
25177e2e9c0cSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
25187e2e9c0cSopenharmony_ci    struct Outer {
25197e2e9c0cSopenharmony_ci        #[serde(flatten)]
25207e2e9c0cSopenharmony_ci        inner: IgnoredAny,
25217e2e9c0cSopenharmony_ci    }
25227e2e9c0cSopenharmony_ci
25237e2e9c0cSopenharmony_ci    assert_de_tokens(
25247e2e9c0cSopenharmony_ci        &Outer { inner: IgnoredAny },
25257e2e9c0cSopenharmony_ci        &[Token::Map { len: None }, Token::MapEnd],
25267e2e9c0cSopenharmony_ci    );
25277e2e9c0cSopenharmony_ci
25287e2e9c0cSopenharmony_ci    assert_de_tokens(
25297e2e9c0cSopenharmony_ci        &Outer { inner: IgnoredAny },
25307e2e9c0cSopenharmony_ci        &[
25317e2e9c0cSopenharmony_ci            Token::Struct {
25327e2e9c0cSopenharmony_ci                name: "DoNotMatter",
25337e2e9c0cSopenharmony_ci                len: 0,
25347e2e9c0cSopenharmony_ci            },
25357e2e9c0cSopenharmony_ci            Token::StructEnd,
25367e2e9c0cSopenharmony_ci        ],
25377e2e9c0cSopenharmony_ci    );
25387e2e9c0cSopenharmony_ci}
25397e2e9c0cSopenharmony_ci
25407e2e9c0cSopenharmony_ci#[test]
25417e2e9c0cSopenharmony_cifn test_transparent_struct() {
25427e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
25437e2e9c0cSopenharmony_ci    #[serde(transparent)]
25447e2e9c0cSopenharmony_ci    struct Transparent {
25457e2e9c0cSopenharmony_ci        #[serde(skip)]
25467e2e9c0cSopenharmony_ci        a: bool,
25477e2e9c0cSopenharmony_ci        b: u32,
25487e2e9c0cSopenharmony_ci        #[serde(skip)]
25497e2e9c0cSopenharmony_ci        c: bool,
25507e2e9c0cSopenharmony_ci        d: PhantomData<()>,
25517e2e9c0cSopenharmony_ci    }
25527e2e9c0cSopenharmony_ci
25537e2e9c0cSopenharmony_ci    assert_tokens(
25547e2e9c0cSopenharmony_ci        &Transparent {
25557e2e9c0cSopenharmony_ci            a: false,
25567e2e9c0cSopenharmony_ci            b: 1,
25577e2e9c0cSopenharmony_ci            c: false,
25587e2e9c0cSopenharmony_ci            d: PhantomData,
25597e2e9c0cSopenharmony_ci        },
25607e2e9c0cSopenharmony_ci        &[Token::U32(1)],
25617e2e9c0cSopenharmony_ci    );
25627e2e9c0cSopenharmony_ci}
25637e2e9c0cSopenharmony_ci
25647e2e9c0cSopenharmony_ci#[test]
25657e2e9c0cSopenharmony_cifn test_transparent_tuple_struct() {
25667e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, PartialEq, Debug)]
25677e2e9c0cSopenharmony_ci    #[serde(transparent)]
25687e2e9c0cSopenharmony_ci    struct Transparent(
25697e2e9c0cSopenharmony_ci        #[serde(skip)] bool,
25707e2e9c0cSopenharmony_ci        u32,
25717e2e9c0cSopenharmony_ci        #[serde(skip)] bool,
25727e2e9c0cSopenharmony_ci        PhantomData<()>,
25737e2e9c0cSopenharmony_ci    );
25747e2e9c0cSopenharmony_ci
25757e2e9c0cSopenharmony_ci    assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]);
25767e2e9c0cSopenharmony_ci}
25777e2e9c0cSopenharmony_ci
25787e2e9c0cSopenharmony_ci#[test]
25797e2e9c0cSopenharmony_cifn test_internally_tagged_unit_enum_with_unknown_fields() {
25807e2e9c0cSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
25817e2e9c0cSopenharmony_ci    #[serde(tag = "t")]
25827e2e9c0cSopenharmony_ci    enum Data {
25837e2e9c0cSopenharmony_ci        A,
25847e2e9c0cSopenharmony_ci    }
25857e2e9c0cSopenharmony_ci
25867e2e9c0cSopenharmony_ci    let data = Data::A;
25877e2e9c0cSopenharmony_ci
25887e2e9c0cSopenharmony_ci    assert_de_tokens(
25897e2e9c0cSopenharmony_ci        &data,
25907e2e9c0cSopenharmony_ci        &[
25917e2e9c0cSopenharmony_ci            Token::Map { len: None },
25927e2e9c0cSopenharmony_ci            Token::Str("t"),
25937e2e9c0cSopenharmony_ci            Token::Str("A"),
25947e2e9c0cSopenharmony_ci            Token::Str("b"),
25957e2e9c0cSopenharmony_ci            Token::I32(0),
25967e2e9c0cSopenharmony_ci            Token::MapEnd,
25977e2e9c0cSopenharmony_ci        ],
25987e2e9c0cSopenharmony_ci    );
25997e2e9c0cSopenharmony_ci}
26007e2e9c0cSopenharmony_ci
26017e2e9c0cSopenharmony_ci#[test]
26027e2e9c0cSopenharmony_cifn test_flatten_any_after_flatten_struct() {
26037e2e9c0cSopenharmony_ci    #[derive(PartialEq, Debug)]
26047e2e9c0cSopenharmony_ci    struct Any;
26057e2e9c0cSopenharmony_ci
26067e2e9c0cSopenharmony_ci    impl<'de> Deserialize<'de> for Any {
26077e2e9c0cSopenharmony_ci        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
26087e2e9c0cSopenharmony_ci        where
26097e2e9c0cSopenharmony_ci            D: Deserializer<'de>,
26107e2e9c0cSopenharmony_ci        {
26117e2e9c0cSopenharmony_ci            struct AnyVisitor;
26127e2e9c0cSopenharmony_ci
26137e2e9c0cSopenharmony_ci            impl<'de> Visitor<'de> for AnyVisitor {
26147e2e9c0cSopenharmony_ci                type Value = Any;
26157e2e9c0cSopenharmony_ci
26167e2e9c0cSopenharmony_ci                fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
26177e2e9c0cSopenharmony_ci                    unimplemented!()
26187e2e9c0cSopenharmony_ci                }
26197e2e9c0cSopenharmony_ci
26207e2e9c0cSopenharmony_ci                fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
26217e2e9c0cSopenharmony_ci                where
26227e2e9c0cSopenharmony_ci                    M: MapAccess<'de>,
26237e2e9c0cSopenharmony_ci                {
26247e2e9c0cSopenharmony_ci                    while let Some((Any, Any)) = map.next_entry()? {}
26257e2e9c0cSopenharmony_ci                    Ok(Any)
26267e2e9c0cSopenharmony_ci                }
26277e2e9c0cSopenharmony_ci            }
26287e2e9c0cSopenharmony_ci
26297e2e9c0cSopenharmony_ci            deserializer.deserialize_any(AnyVisitor)
26307e2e9c0cSopenharmony_ci        }
26317e2e9c0cSopenharmony_ci    }
26327e2e9c0cSopenharmony_ci
26337e2e9c0cSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
26347e2e9c0cSopenharmony_ci    struct Outer {
26357e2e9c0cSopenharmony_ci        #[serde(flatten)]
26367e2e9c0cSopenharmony_ci        inner: Inner,
26377e2e9c0cSopenharmony_ci        #[serde(flatten)]
26387e2e9c0cSopenharmony_ci        extra: Any,
26397e2e9c0cSopenharmony_ci    }
26407e2e9c0cSopenharmony_ci
26417e2e9c0cSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
26427e2e9c0cSopenharmony_ci    struct Inner {
26437e2e9c0cSopenharmony_ci        inner: i32,
26447e2e9c0cSopenharmony_ci    }
26457e2e9c0cSopenharmony_ci
26467e2e9c0cSopenharmony_ci    let s = Outer {
26477e2e9c0cSopenharmony_ci        inner: Inner { inner: 0 },
26487e2e9c0cSopenharmony_ci        extra: Any,
26497e2e9c0cSopenharmony_ci    };
26507e2e9c0cSopenharmony_ci
26517e2e9c0cSopenharmony_ci    assert_de_tokens(
26527e2e9c0cSopenharmony_ci        &s,
26537e2e9c0cSopenharmony_ci        &[
26547e2e9c0cSopenharmony_ci            Token::Map { len: None },
26557e2e9c0cSopenharmony_ci            Token::Str("inner"),
26567e2e9c0cSopenharmony_ci            Token::I32(0),
26577e2e9c0cSopenharmony_ci            Token::MapEnd,
26587e2e9c0cSopenharmony_ci        ],
26597e2e9c0cSopenharmony_ci    );
26607e2e9c0cSopenharmony_ci}
26617e2e9c0cSopenharmony_ci
26627e2e9c0cSopenharmony_ci#[test]
26637e2e9c0cSopenharmony_cifn test_alias_in_flatten_context() {
26647e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
26657e2e9c0cSopenharmony_ci    struct Outer {
26667e2e9c0cSopenharmony_ci        #[serde(flatten)]
26677e2e9c0cSopenharmony_ci        a: AliasStruct,
26687e2e9c0cSopenharmony_ci        b: i32,
26697e2e9c0cSopenharmony_ci    }
26707e2e9c0cSopenharmony_ci
26717e2e9c0cSopenharmony_ci    assert_de_tokens(
26727e2e9c0cSopenharmony_ci        &Outer {
26737e2e9c0cSopenharmony_ci            a: AliasStruct {
26747e2e9c0cSopenharmony_ci                a1: 1,
26757e2e9c0cSopenharmony_ci                a2: 2,
26767e2e9c0cSopenharmony_ci                a4: 4,
26777e2e9c0cSopenharmony_ci            },
26787e2e9c0cSopenharmony_ci            b: 7,
26797e2e9c0cSopenharmony_ci        },
26807e2e9c0cSopenharmony_ci        &[
26817e2e9c0cSopenharmony_ci            Token::Struct {
26827e2e9c0cSopenharmony_ci                name: "Outer",
26837e2e9c0cSopenharmony_ci                len: 4,
26847e2e9c0cSopenharmony_ci            },
26857e2e9c0cSopenharmony_ci            Token::Str("a1"),
26867e2e9c0cSopenharmony_ci            Token::I32(1),
26877e2e9c0cSopenharmony_ci            Token::Str("a2"),
26887e2e9c0cSopenharmony_ci            Token::I32(2),
26897e2e9c0cSopenharmony_ci            Token::Str("a5"),
26907e2e9c0cSopenharmony_ci            Token::I32(4),
26917e2e9c0cSopenharmony_ci            Token::Str("b"),
26927e2e9c0cSopenharmony_ci            Token::I32(7),
26937e2e9c0cSopenharmony_ci            Token::StructEnd,
26947e2e9c0cSopenharmony_ci        ],
26957e2e9c0cSopenharmony_ci    );
26967e2e9c0cSopenharmony_ci
26977e2e9c0cSopenharmony_ci    assert_de_tokens(
26987e2e9c0cSopenharmony_ci        &Outer {
26997e2e9c0cSopenharmony_ci            a: AliasStruct {
27007e2e9c0cSopenharmony_ci                a1: 1,
27017e2e9c0cSopenharmony_ci                a2: 2,
27027e2e9c0cSopenharmony_ci                a4: 4,
27037e2e9c0cSopenharmony_ci            },
27047e2e9c0cSopenharmony_ci            b: 7,
27057e2e9c0cSopenharmony_ci        },
27067e2e9c0cSopenharmony_ci        &[
27077e2e9c0cSopenharmony_ci            Token::Struct {
27087e2e9c0cSopenharmony_ci                name: "Outer",
27097e2e9c0cSopenharmony_ci                len: 4,
27107e2e9c0cSopenharmony_ci            },
27117e2e9c0cSopenharmony_ci            Token::Str("a1"),
27127e2e9c0cSopenharmony_ci            Token::I32(1),
27137e2e9c0cSopenharmony_ci            Token::Str("a2"),
27147e2e9c0cSopenharmony_ci            Token::I32(2),
27157e2e9c0cSopenharmony_ci            Token::Str("a6"),
27167e2e9c0cSopenharmony_ci            Token::I32(4),
27177e2e9c0cSopenharmony_ci            Token::Str("b"),
27187e2e9c0cSopenharmony_ci            Token::I32(7),
27197e2e9c0cSopenharmony_ci            Token::StructEnd,
27207e2e9c0cSopenharmony_ci        ],
27217e2e9c0cSopenharmony_ci    );
27227e2e9c0cSopenharmony_ci}
27237e2e9c0cSopenharmony_ci
27247e2e9c0cSopenharmony_ci#[test]
27257e2e9c0cSopenharmony_cifn test_expecting_message() {
27267e2e9c0cSopenharmony_ci    #[derive(Deserialize, PartialEq, Debug)]
27277e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27287e2e9c0cSopenharmony_ci    struct Unit;
27297e2e9c0cSopenharmony_ci
27307e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
27317e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27327e2e9c0cSopenharmony_ci    struct Newtype(bool);
27337e2e9c0cSopenharmony_ci
27347e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
27357e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27367e2e9c0cSopenharmony_ci    struct Tuple(u32, bool);
27377e2e9c0cSopenharmony_ci
27387e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
27397e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27407e2e9c0cSopenharmony_ci    struct Struct {
27417e2e9c0cSopenharmony_ci        #[allow(dead_code)]
27427e2e9c0cSopenharmony_ci        question: String,
27437e2e9c0cSopenharmony_ci        #[allow(dead_code)]
27447e2e9c0cSopenharmony_ci        answer: u32,
27457e2e9c0cSopenharmony_ci    }
27467e2e9c0cSopenharmony_ci
27477e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Unit>(
27487e2e9c0cSopenharmony_ci        &[Token::Str("Unit")],
27497e2e9c0cSopenharmony_ci        r#"invalid type: string "Unit", expected something strange..."#,
27507e2e9c0cSopenharmony_ci    );
27517e2e9c0cSopenharmony_ci
27527e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Newtype>(
27537e2e9c0cSopenharmony_ci        &[Token::Str("Newtype")],
27547e2e9c0cSopenharmony_ci        r#"invalid type: string "Newtype", expected something strange..."#,
27557e2e9c0cSopenharmony_ci    );
27567e2e9c0cSopenharmony_ci
27577e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Tuple>(
27587e2e9c0cSopenharmony_ci        &[Token::Str("Tuple")],
27597e2e9c0cSopenharmony_ci        r#"invalid type: string "Tuple", expected something strange..."#,
27607e2e9c0cSopenharmony_ci    );
27617e2e9c0cSopenharmony_ci
27627e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Struct>(
27637e2e9c0cSopenharmony_ci        &[Token::Str("Struct")],
27647e2e9c0cSopenharmony_ci        r#"invalid type: string "Struct", expected something strange..."#,
27657e2e9c0cSopenharmony_ci    );
27667e2e9c0cSopenharmony_ci}
27677e2e9c0cSopenharmony_ci
27687e2e9c0cSopenharmony_ci#[test]
27697e2e9c0cSopenharmony_cifn test_expecting_message_externally_tagged_enum() {
27707e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
27717e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27727e2e9c0cSopenharmony_ci    enum Enum {
27737e2e9c0cSopenharmony_ci        ExternallyTagged,
27747e2e9c0cSopenharmony_ci    }
27757e2e9c0cSopenharmony_ci
27767e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
27777e2e9c0cSopenharmony_ci        &[Token::Str("ExternallyTagged")],
27787e2e9c0cSopenharmony_ci        r#"invalid type: string "ExternallyTagged", expected something strange..."#,
27797e2e9c0cSopenharmony_ci    );
27807e2e9c0cSopenharmony_ci
27817e2e9c0cSopenharmony_ci    // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
27827e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
27837e2e9c0cSopenharmony_ci        &[Token::Enum { name: "Enum" }, Token::Unit],
27847e2e9c0cSopenharmony_ci        "invalid type: unit value, expected variant identifier",
27857e2e9c0cSopenharmony_ci    );
27867e2e9c0cSopenharmony_ci}
27877e2e9c0cSopenharmony_ci
27887e2e9c0cSopenharmony_ci#[test]
27897e2e9c0cSopenharmony_cifn test_expecting_message_internally_tagged_enum() {
27907e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
27917e2e9c0cSopenharmony_ci    #[serde(tag = "tag")]
27927e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
27937e2e9c0cSopenharmony_ci    enum Enum {
27947e2e9c0cSopenharmony_ci        InternallyTagged,
27957e2e9c0cSopenharmony_ci    }
27967e2e9c0cSopenharmony_ci
27977e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
27987e2e9c0cSopenharmony_ci        &[Token::Str("InternallyTagged")],
27997e2e9c0cSopenharmony_ci        r#"invalid type: string "InternallyTagged", expected something strange..."#,
28007e2e9c0cSopenharmony_ci    );
28017e2e9c0cSopenharmony_ci
28027e2e9c0cSopenharmony_ci    // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
28037e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
28047e2e9c0cSopenharmony_ci        &[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
28057e2e9c0cSopenharmony_ci        "invalid type: unit value, expected variant identifier",
28067e2e9c0cSopenharmony_ci    );
28077e2e9c0cSopenharmony_ci}
28087e2e9c0cSopenharmony_ci
28097e2e9c0cSopenharmony_ci#[test]
28107e2e9c0cSopenharmony_cifn test_expecting_message_adjacently_tagged_enum() {
28117e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
28127e2e9c0cSopenharmony_ci    #[serde(tag = "tag", content = "content")]
28137e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
28147e2e9c0cSopenharmony_ci    enum Enum {
28157e2e9c0cSopenharmony_ci        AdjacentlyTagged,
28167e2e9c0cSopenharmony_ci    }
28177e2e9c0cSopenharmony_ci
28187e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
28197e2e9c0cSopenharmony_ci        &[Token::Str("AdjacentlyTagged")],
28207e2e9c0cSopenharmony_ci        r#"invalid type: string "AdjacentlyTagged", expected something strange..."#,
28217e2e9c0cSopenharmony_ci    );
28227e2e9c0cSopenharmony_ci
28237e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
28247e2e9c0cSopenharmony_ci        &[Token::Map { len: None }, Token::Unit],
28257e2e9c0cSopenharmony_ci        r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#,
28267e2e9c0cSopenharmony_ci    );
28277e2e9c0cSopenharmony_ci
28287e2e9c0cSopenharmony_ci    // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
28297e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(
28307e2e9c0cSopenharmony_ci        &[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
28317e2e9c0cSopenharmony_ci        "invalid type: unit value, expected variant of enum Enum",
28327e2e9c0cSopenharmony_ci    );
28337e2e9c0cSopenharmony_ci}
28347e2e9c0cSopenharmony_ci
28357e2e9c0cSopenharmony_ci#[test]
28367e2e9c0cSopenharmony_cifn test_expecting_message_untagged_tagged_enum() {
28377e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
28387e2e9c0cSopenharmony_ci    #[serde(untagged)]
28397e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
28407e2e9c0cSopenharmony_ci    enum Enum {
28417e2e9c0cSopenharmony_ci        Untagged,
28427e2e9c0cSopenharmony_ci    }
28437e2e9c0cSopenharmony_ci
28447e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], "something strange...");
28457e2e9c0cSopenharmony_ci}
28467e2e9c0cSopenharmony_ci
28477e2e9c0cSopenharmony_ci#[test]
28487e2e9c0cSopenharmony_cifn test_expecting_message_identifier_enum() {
28497e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
28507e2e9c0cSopenharmony_ci    #[serde(field_identifier)]
28517e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
28527e2e9c0cSopenharmony_ci    enum FieldEnum {
28537e2e9c0cSopenharmony_ci        Field,
28547e2e9c0cSopenharmony_ci    }
28557e2e9c0cSopenharmony_ci
28567e2e9c0cSopenharmony_ci    #[derive(Deserialize)]
28577e2e9c0cSopenharmony_ci    #[serde(variant_identifier)]
28587e2e9c0cSopenharmony_ci    #[serde(expecting = "something strange...")]
28597e2e9c0cSopenharmony_ci    enum VariantEnum {
28607e2e9c0cSopenharmony_ci        Variant,
28617e2e9c0cSopenharmony_ci    }
28627e2e9c0cSopenharmony_ci
28637e2e9c0cSopenharmony_ci    assert_de_tokens_error::<FieldEnum>(
28647e2e9c0cSopenharmony_ci        &[Token::Unit],
28657e2e9c0cSopenharmony_ci        "invalid type: unit value, expected something strange...",
28667e2e9c0cSopenharmony_ci    );
28677e2e9c0cSopenharmony_ci
28687e2e9c0cSopenharmony_ci    assert_de_tokens_error::<FieldEnum>(
28697e2e9c0cSopenharmony_ci        &[
28707e2e9c0cSopenharmony_ci            Token::Enum { name: "FieldEnum" },
28717e2e9c0cSopenharmony_ci            Token::Str("Unknown"),
28727e2e9c0cSopenharmony_ci            Token::None,
28737e2e9c0cSopenharmony_ci        ],
28747e2e9c0cSopenharmony_ci        "invalid type: map, expected something strange...",
28757e2e9c0cSopenharmony_ci    );
28767e2e9c0cSopenharmony_ci
28777e2e9c0cSopenharmony_ci    assert_de_tokens_error::<VariantEnum>(
28787e2e9c0cSopenharmony_ci        &[Token::Unit],
28797e2e9c0cSopenharmony_ci        "invalid type: unit value, expected something strange...",
28807e2e9c0cSopenharmony_ci    );
28817e2e9c0cSopenharmony_ci
28827e2e9c0cSopenharmony_ci    assert_de_tokens_error::<VariantEnum>(
28837e2e9c0cSopenharmony_ci        &[
28847e2e9c0cSopenharmony_ci            Token::Enum {
28857e2e9c0cSopenharmony_ci                name: "VariantEnum",
28867e2e9c0cSopenharmony_ci            },
28877e2e9c0cSopenharmony_ci            Token::Str("Unknown"),
28887e2e9c0cSopenharmony_ci            Token::None,
28897e2e9c0cSopenharmony_ci        ],
28907e2e9c0cSopenharmony_ci        "invalid type: map, expected something strange...",
28917e2e9c0cSopenharmony_ci    );
28927e2e9c0cSopenharmony_ci}
28937e2e9c0cSopenharmony_ci
28947e2e9c0cSopenharmony_cimod flatten {
28957e2e9c0cSopenharmony_ci    use super::*;
28967e2e9c0cSopenharmony_ci
28977e2e9c0cSopenharmony_ci    mod enum_ {
28987e2e9c0cSopenharmony_ci        use super::*;
28997e2e9c0cSopenharmony_ci
29007e2e9c0cSopenharmony_ci        mod externally_tagged {
29017e2e9c0cSopenharmony_ci            use super::*;
29027e2e9c0cSopenharmony_ci            use std::iter::FromIterator;
29037e2e9c0cSopenharmony_ci
29047e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
29057e2e9c0cSopenharmony_ci            struct Flatten {
29067e2e9c0cSopenharmony_ci                #[serde(flatten)]
29077e2e9c0cSopenharmony_ci                data: Enum,
29087e2e9c0cSopenharmony_ci
29097e2e9c0cSopenharmony_ci                #[serde(flatten)]
29107e2e9c0cSopenharmony_ci                extra: HashMap<String, String>,
29117e2e9c0cSopenharmony_ci            }
29127e2e9c0cSopenharmony_ci
29137e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
29147e2e9c0cSopenharmony_ci            enum Enum {
29157e2e9c0cSopenharmony_ci                Newtype(HashMap<String, String>),
29167e2e9c0cSopenharmony_ci                Tuple(u32, u32),
29177e2e9c0cSopenharmony_ci                Struct { index: u32, value: u32 },
29187e2e9c0cSopenharmony_ci            }
29197e2e9c0cSopenharmony_ci
29207e2e9c0cSopenharmony_ci            #[test]
29217e2e9c0cSopenharmony_ci            fn newtype() {
29227e2e9c0cSopenharmony_ci                assert_tokens(
29237e2e9c0cSopenharmony_ci                    &Flatten {
29247e2e9c0cSopenharmony_ci                        data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])),
29257e2e9c0cSopenharmony_ci                        extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
29267e2e9c0cSopenharmony_ci                    },
29277e2e9c0cSopenharmony_ci                    &[
29287e2e9c0cSopenharmony_ci                        Token::Map { len: None },
29297e2e9c0cSopenharmony_ci                        Token::Str("Newtype"), // variant
29307e2e9c0cSopenharmony_ci                        Token::Map { len: Some(1) },
29317e2e9c0cSopenharmony_ci                        Token::Str("key"),
29327e2e9c0cSopenharmony_ci                        Token::Str("value"),
29337e2e9c0cSopenharmony_ci                        Token::MapEnd,
29347e2e9c0cSopenharmony_ci                        Token::Str("extra_key"),
29357e2e9c0cSopenharmony_ci                        Token::Str("extra value"),
29367e2e9c0cSopenharmony_ci                        Token::MapEnd,
29377e2e9c0cSopenharmony_ci                    ],
29387e2e9c0cSopenharmony_ci                );
29397e2e9c0cSopenharmony_ci            }
29407e2e9c0cSopenharmony_ci
29417e2e9c0cSopenharmony_ci            // Reaches crate::private::de::content::VariantDeserializer::tuple_variant
29427e2e9c0cSopenharmony_ci            // Content::Seq case
29437e2e9c0cSopenharmony_ci            // via FlatMapDeserializer::deserialize_enum
29447e2e9c0cSopenharmony_ci            #[test]
29457e2e9c0cSopenharmony_ci            fn tuple() {
29467e2e9c0cSopenharmony_ci                assert_tokens(
29477e2e9c0cSopenharmony_ci                    &Flatten {
29487e2e9c0cSopenharmony_ci                        data: Enum::Tuple(0, 42),
29497e2e9c0cSopenharmony_ci                        extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
29507e2e9c0cSopenharmony_ci                    },
29517e2e9c0cSopenharmony_ci                    &[
29527e2e9c0cSopenharmony_ci                        Token::Map { len: None },
29537e2e9c0cSopenharmony_ci                        Token::Str("Tuple"), // variant
29547e2e9c0cSopenharmony_ci                        Token::Seq { len: Some(2) },
29557e2e9c0cSopenharmony_ci                        Token::U32(0),
29567e2e9c0cSopenharmony_ci                        Token::U32(42),
29577e2e9c0cSopenharmony_ci                        Token::SeqEnd,
29587e2e9c0cSopenharmony_ci                        Token::Str("extra_key"),
29597e2e9c0cSopenharmony_ci                        Token::Str("extra value"),
29607e2e9c0cSopenharmony_ci                        Token::MapEnd,
29617e2e9c0cSopenharmony_ci                    ],
29627e2e9c0cSopenharmony_ci                );
29637e2e9c0cSopenharmony_ci            }
29647e2e9c0cSopenharmony_ci
29657e2e9c0cSopenharmony_ci            // Reaches crate::private::de::content::VariantDeserializer::struct_variant
29667e2e9c0cSopenharmony_ci            // Content::Seq case
29677e2e9c0cSopenharmony_ci            // via FlatMapDeserializer::deserialize_enum
29687e2e9c0cSopenharmony_ci            #[test]
29697e2e9c0cSopenharmony_ci            fn struct_from_seq() {
29707e2e9c0cSopenharmony_ci                assert_de_tokens(
29717e2e9c0cSopenharmony_ci                    &Flatten {
29727e2e9c0cSopenharmony_ci                        data: Enum::Struct {
29737e2e9c0cSopenharmony_ci                            index: 0,
29747e2e9c0cSopenharmony_ci                            value: 42,
29757e2e9c0cSopenharmony_ci                        },
29767e2e9c0cSopenharmony_ci                        extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
29777e2e9c0cSopenharmony_ci                    },
29787e2e9c0cSopenharmony_ci                    &[
29797e2e9c0cSopenharmony_ci                        Token::Map { len: None },
29807e2e9c0cSopenharmony_ci                        Token::Str("Struct"), // variant
29817e2e9c0cSopenharmony_ci                        Token::Seq { len: Some(2) },
29827e2e9c0cSopenharmony_ci                        Token::U32(0),  // index
29837e2e9c0cSopenharmony_ci                        Token::U32(42), // value
29847e2e9c0cSopenharmony_ci                        Token::SeqEnd,
29857e2e9c0cSopenharmony_ci                        Token::Str("extra_key"),
29867e2e9c0cSopenharmony_ci                        Token::Str("extra value"),
29877e2e9c0cSopenharmony_ci                        Token::MapEnd,
29887e2e9c0cSopenharmony_ci                    ],
29897e2e9c0cSopenharmony_ci                );
29907e2e9c0cSopenharmony_ci            }
29917e2e9c0cSopenharmony_ci
29927e2e9c0cSopenharmony_ci            // Reaches crate::private::de::content::VariantDeserializer::struct_variant
29937e2e9c0cSopenharmony_ci            // Content::Map case
29947e2e9c0cSopenharmony_ci            // via FlatMapDeserializer::deserialize_enum
29957e2e9c0cSopenharmony_ci            #[test]
29967e2e9c0cSopenharmony_ci            fn struct_from_map() {
29977e2e9c0cSopenharmony_ci                assert_tokens(
29987e2e9c0cSopenharmony_ci                    &Flatten {
29997e2e9c0cSopenharmony_ci                        data: Enum::Struct {
30007e2e9c0cSopenharmony_ci                            index: 0,
30017e2e9c0cSopenharmony_ci                            value: 42,
30027e2e9c0cSopenharmony_ci                        },
30037e2e9c0cSopenharmony_ci                        extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
30047e2e9c0cSopenharmony_ci                    },
30057e2e9c0cSopenharmony_ci                    &[
30067e2e9c0cSopenharmony_ci                        Token::Map { len: None },
30077e2e9c0cSopenharmony_ci                        Token::Str("Struct"), // variant
30087e2e9c0cSopenharmony_ci                        Token::Struct {
30097e2e9c0cSopenharmony_ci                            len: 2,
30107e2e9c0cSopenharmony_ci                            name: "Struct",
30117e2e9c0cSopenharmony_ci                        },
30127e2e9c0cSopenharmony_ci                        Token::Str("index"),
30137e2e9c0cSopenharmony_ci                        Token::U32(0),
30147e2e9c0cSopenharmony_ci                        Token::Str("value"),
30157e2e9c0cSopenharmony_ci                        Token::U32(42),
30167e2e9c0cSopenharmony_ci                        Token::StructEnd,
30177e2e9c0cSopenharmony_ci                        Token::Str("extra_key"),
30187e2e9c0cSopenharmony_ci                        Token::Str("extra value"),
30197e2e9c0cSopenharmony_ci                        Token::MapEnd,
30207e2e9c0cSopenharmony_ci                    ],
30217e2e9c0cSopenharmony_ci                );
30227e2e9c0cSopenharmony_ci            }
30237e2e9c0cSopenharmony_ci        }
30247e2e9c0cSopenharmony_ci
30257e2e9c0cSopenharmony_ci        mod adjacently_tagged {
30267e2e9c0cSopenharmony_ci            use super::*;
30277e2e9c0cSopenharmony_ci
30287e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
30297e2e9c0cSopenharmony_ci            struct Flatten {
30307e2e9c0cSopenharmony_ci                outer: u32,
30317e2e9c0cSopenharmony_ci
30327e2e9c0cSopenharmony_ci                #[serde(flatten)]
30337e2e9c0cSopenharmony_ci                data: NewtypeWrapper,
30347e2e9c0cSopenharmony_ci            }
30357e2e9c0cSopenharmony_ci
30367e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
30377e2e9c0cSopenharmony_ci            struct NewtypeWrapper(pub Enum);
30387e2e9c0cSopenharmony_ci
30397e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
30407e2e9c0cSopenharmony_ci            #[serde(tag = "tag", content = "content")]
30417e2e9c0cSopenharmony_ci            enum Enum {
30427e2e9c0cSopenharmony_ci                Newtype(NewtypeVariant),
30437e2e9c0cSopenharmony_ci                Struct { index: u32, value: u32 },
30447e2e9c0cSopenharmony_ci            }
30457e2e9c0cSopenharmony_ci
30467e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
30477e2e9c0cSopenharmony_ci            struct NewtypeVariant {
30487e2e9c0cSopenharmony_ci                value: u32,
30497e2e9c0cSopenharmony_ci            }
30507e2e9c0cSopenharmony_ci
30517e2e9c0cSopenharmony_ci            #[test]
30527e2e9c0cSopenharmony_ci            fn struct_() {
30537e2e9c0cSopenharmony_ci                assert_tokens(
30547e2e9c0cSopenharmony_ci                    &Flatten {
30557e2e9c0cSopenharmony_ci                        outer: 42,
30567e2e9c0cSopenharmony_ci                        data: NewtypeWrapper(Enum::Struct {
30577e2e9c0cSopenharmony_ci                            index: 0,
30587e2e9c0cSopenharmony_ci                            value: 42,
30597e2e9c0cSopenharmony_ci                        }),
30607e2e9c0cSopenharmony_ci                    },
30617e2e9c0cSopenharmony_ci                    &[
30627e2e9c0cSopenharmony_ci                        Token::Map { len: None },
30637e2e9c0cSopenharmony_ci                        Token::Str("outer"),
30647e2e9c0cSopenharmony_ci                        Token::U32(42),
30657e2e9c0cSopenharmony_ci                        Token::Str("tag"),
30667e2e9c0cSopenharmony_ci                        Token::UnitVariant {
30677e2e9c0cSopenharmony_ci                            name: "Enum",
30687e2e9c0cSopenharmony_ci                            variant: "Struct",
30697e2e9c0cSopenharmony_ci                        },
30707e2e9c0cSopenharmony_ci                        Token::Str("content"),
30717e2e9c0cSopenharmony_ci                        Token::Struct {
30727e2e9c0cSopenharmony_ci                            len: 2,
30737e2e9c0cSopenharmony_ci                            name: "Struct",
30747e2e9c0cSopenharmony_ci                        },
30757e2e9c0cSopenharmony_ci                        Token::Str("index"),
30767e2e9c0cSopenharmony_ci                        Token::U32(0),
30777e2e9c0cSopenharmony_ci                        Token::Str("value"),
30787e2e9c0cSopenharmony_ci                        Token::U32(42),
30797e2e9c0cSopenharmony_ci                        Token::StructEnd,
30807e2e9c0cSopenharmony_ci                        Token::MapEnd,
30817e2e9c0cSopenharmony_ci                    ],
30827e2e9c0cSopenharmony_ci                );
30837e2e9c0cSopenharmony_ci            }
30847e2e9c0cSopenharmony_ci
30857e2e9c0cSopenharmony_ci            #[test]
30867e2e9c0cSopenharmony_ci            fn newtype() {
30877e2e9c0cSopenharmony_ci                assert_tokens(
30887e2e9c0cSopenharmony_ci                    &Flatten {
30897e2e9c0cSopenharmony_ci                        outer: 42,
30907e2e9c0cSopenharmony_ci                        data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })),
30917e2e9c0cSopenharmony_ci                    },
30927e2e9c0cSopenharmony_ci                    &[
30937e2e9c0cSopenharmony_ci                        Token::Map { len: None },
30947e2e9c0cSopenharmony_ci                        Token::Str("outer"),
30957e2e9c0cSopenharmony_ci                        Token::U32(42),
30967e2e9c0cSopenharmony_ci                        Token::Str("tag"),
30977e2e9c0cSopenharmony_ci                        Token::UnitVariant {
30987e2e9c0cSopenharmony_ci                            name: "Enum",
30997e2e9c0cSopenharmony_ci                            variant: "Newtype",
31007e2e9c0cSopenharmony_ci                        },
31017e2e9c0cSopenharmony_ci                        Token::Str("content"),
31027e2e9c0cSopenharmony_ci                        Token::Struct {
31037e2e9c0cSopenharmony_ci                            len: 1,
31047e2e9c0cSopenharmony_ci                            name: "NewtypeVariant",
31057e2e9c0cSopenharmony_ci                        },
31067e2e9c0cSopenharmony_ci                        Token::Str("value"),
31077e2e9c0cSopenharmony_ci                        Token::U32(23),
31087e2e9c0cSopenharmony_ci                        Token::StructEnd,
31097e2e9c0cSopenharmony_ci                        Token::MapEnd,
31107e2e9c0cSopenharmony_ci                    ],
31117e2e9c0cSopenharmony_ci                );
31127e2e9c0cSopenharmony_ci            }
31137e2e9c0cSopenharmony_ci        }
31147e2e9c0cSopenharmony_ci
31157e2e9c0cSopenharmony_ci        mod internally_tagged {
31167e2e9c0cSopenharmony_ci            use super::*;
31177e2e9c0cSopenharmony_ci
31187e2e9c0cSopenharmony_ci            #[test]
31197e2e9c0cSopenharmony_ci            fn structs() {
31207e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Serialize, Deserialize)]
31217e2e9c0cSopenharmony_ci                struct Flatten {
31227e2e9c0cSopenharmony_ci                    #[serde(flatten)]
31237e2e9c0cSopenharmony_ci                    x: X,
31247e2e9c0cSopenharmony_ci                    #[serde(flatten)]
31257e2e9c0cSopenharmony_ci                    y: Y,
31267e2e9c0cSopenharmony_ci                }
31277e2e9c0cSopenharmony_ci
31287e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Serialize, Deserialize)]
31297e2e9c0cSopenharmony_ci                #[serde(tag = "typeX")]
31307e2e9c0cSopenharmony_ci                enum X {
31317e2e9c0cSopenharmony_ci                    A { a: i32 },
31327e2e9c0cSopenharmony_ci                    B { b: i32 },
31337e2e9c0cSopenharmony_ci                }
31347e2e9c0cSopenharmony_ci
31357e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Serialize, Deserialize)]
31367e2e9c0cSopenharmony_ci                #[serde(tag = "typeY")]
31377e2e9c0cSopenharmony_ci                enum Y {
31387e2e9c0cSopenharmony_ci                    C { c: i32 },
31397e2e9c0cSopenharmony_ci                    D { d: i32 },
31407e2e9c0cSopenharmony_ci                }
31417e2e9c0cSopenharmony_ci
31427e2e9c0cSopenharmony_ci                assert_tokens(
31437e2e9c0cSopenharmony_ci                    &Flatten {
31447e2e9c0cSopenharmony_ci                        x: X::B { b: 1 },
31457e2e9c0cSopenharmony_ci                        y: Y::D { d: 2 },
31467e2e9c0cSopenharmony_ci                    },
31477e2e9c0cSopenharmony_ci                    &[
31487e2e9c0cSopenharmony_ci                        Token::Map { len: None },
31497e2e9c0cSopenharmony_ci                        Token::Str("typeX"),
31507e2e9c0cSopenharmony_ci                        Token::Str("B"),
31517e2e9c0cSopenharmony_ci                        Token::Str("b"),
31527e2e9c0cSopenharmony_ci                        Token::I32(1),
31537e2e9c0cSopenharmony_ci                        Token::Str("typeY"),
31547e2e9c0cSopenharmony_ci                        Token::Str("D"),
31557e2e9c0cSopenharmony_ci                        Token::Str("d"),
31567e2e9c0cSopenharmony_ci                        Token::I32(2),
31577e2e9c0cSopenharmony_ci                        Token::MapEnd,
31587e2e9c0cSopenharmony_ci                    ],
31597e2e9c0cSopenharmony_ci                );
31607e2e9c0cSopenharmony_ci            }
31617e2e9c0cSopenharmony_ci
31627e2e9c0cSopenharmony_ci            #[test]
31637e2e9c0cSopenharmony_ci            fn unit_enum_with_unknown_fields() {
31647e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Deserialize)]
31657e2e9c0cSopenharmony_ci                struct Flatten {
31667e2e9c0cSopenharmony_ci                    #[serde(flatten)]
31677e2e9c0cSopenharmony_ci                    x: X,
31687e2e9c0cSopenharmony_ci                    #[serde(flatten)]
31697e2e9c0cSopenharmony_ci                    y: Y,
31707e2e9c0cSopenharmony_ci                }
31717e2e9c0cSopenharmony_ci
31727e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Deserialize)]
31737e2e9c0cSopenharmony_ci                #[serde(tag = "typeX")]
31747e2e9c0cSopenharmony_ci                enum X {
31757e2e9c0cSopenharmony_ci                    A,
31767e2e9c0cSopenharmony_ci                }
31777e2e9c0cSopenharmony_ci
31787e2e9c0cSopenharmony_ci                #[derive(Debug, PartialEq, Deserialize)]
31797e2e9c0cSopenharmony_ci                #[serde(tag = "typeY")]
31807e2e9c0cSopenharmony_ci                enum Y {
31817e2e9c0cSopenharmony_ci                    B { c: u32 },
31827e2e9c0cSopenharmony_ci                }
31837e2e9c0cSopenharmony_ci
31847e2e9c0cSopenharmony_ci                assert_de_tokens(
31857e2e9c0cSopenharmony_ci                    &Flatten {
31867e2e9c0cSopenharmony_ci                        x: X::A,
31877e2e9c0cSopenharmony_ci                        y: Y::B { c: 0 },
31887e2e9c0cSopenharmony_ci                    },
31897e2e9c0cSopenharmony_ci                    &[
31907e2e9c0cSopenharmony_ci                        Token::Map { len: None },
31917e2e9c0cSopenharmony_ci                        Token::Str("typeX"),
31927e2e9c0cSopenharmony_ci                        Token::Str("A"),
31937e2e9c0cSopenharmony_ci                        Token::Str("typeY"),
31947e2e9c0cSopenharmony_ci                        Token::Str("B"),
31957e2e9c0cSopenharmony_ci                        Token::Str("c"),
31967e2e9c0cSopenharmony_ci                        Token::I32(0),
31977e2e9c0cSopenharmony_ci                        Token::MapEnd,
31987e2e9c0cSopenharmony_ci                    ],
31997e2e9c0cSopenharmony_ci                );
32007e2e9c0cSopenharmony_ci            }
32017e2e9c0cSopenharmony_ci        }
32027e2e9c0cSopenharmony_ci
32037e2e9c0cSopenharmony_ci        mod untagged {
32047e2e9c0cSopenharmony_ci            use super::*;
32057e2e9c0cSopenharmony_ci
32067e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
32077e2e9c0cSopenharmony_ci            struct Flatten {
32087e2e9c0cSopenharmony_ci                #[serde(flatten)]
32097e2e9c0cSopenharmony_ci                data: Enum,
32107e2e9c0cSopenharmony_ci            }
32117e2e9c0cSopenharmony_ci
32127e2e9c0cSopenharmony_ci            #[derive(Debug, PartialEq, Serialize, Deserialize)]
32137e2e9c0cSopenharmony_ci            #[serde(untagged)]
32147e2e9c0cSopenharmony_ci            enum Enum {
32157e2e9c0cSopenharmony_ci                Struct { a: i32 },
32167e2e9c0cSopenharmony_ci            }
32177e2e9c0cSopenharmony_ci
32187e2e9c0cSopenharmony_ci            #[test]
32197e2e9c0cSopenharmony_ci            fn struct_() {
32207e2e9c0cSopenharmony_ci                assert_tokens(
32217e2e9c0cSopenharmony_ci                    &Flatten {
32227e2e9c0cSopenharmony_ci                        data: Enum::Struct { a: 0 },
32237e2e9c0cSopenharmony_ci                    },
32247e2e9c0cSopenharmony_ci                    &[
32257e2e9c0cSopenharmony_ci                        Token::Map { len: None },
32267e2e9c0cSopenharmony_ci                        Token::Str("a"),
32277e2e9c0cSopenharmony_ci                        Token::I32(0),
32287e2e9c0cSopenharmony_ci                        Token::MapEnd,
32297e2e9c0cSopenharmony_ci                    ],
32307e2e9c0cSopenharmony_ci                );
32317e2e9c0cSopenharmony_ci            }
32327e2e9c0cSopenharmony_ci        }
32337e2e9c0cSopenharmony_ci    }
32347e2e9c0cSopenharmony_ci}
3235