17e2e9c0cSopenharmony_ci#![deny(trivial_numeric_casts)]
27e2e9c0cSopenharmony_ci#![allow(
37e2e9c0cSopenharmony_ci    clippy::derive_partial_eq_without_eq,
47e2e9c0cSopenharmony_ci    clippy::enum_variant_names,
57e2e9c0cSopenharmony_ci    clippy::redundant_field_names,
67e2e9c0cSopenharmony_ci    clippy::too_many_lines
77e2e9c0cSopenharmony_ci)]
87e2e9c0cSopenharmony_ci
97e2e9c0cSopenharmony_cimod bytes;
107e2e9c0cSopenharmony_ci
117e2e9c0cSopenharmony_ciuse serde_derive::{Deserialize, Serialize};
127e2e9c0cSopenharmony_ciuse serde_test::{
137e2e9c0cSopenharmony_ci    assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token,
147e2e9c0cSopenharmony_ci};
157e2e9c0cSopenharmony_ciuse std::collections::BTreeMap;
167e2e9c0cSopenharmony_ciuse std::marker::PhantomData;
177e2e9c0cSopenharmony_ci
187e2e9c0cSopenharmony_ci// That tests that the derived Serialize implementation doesn't trigger
197e2e9c0cSopenharmony_ci// any warning about `serializer` not being used, in case of empty enums.
207e2e9c0cSopenharmony_ci#[derive(Serialize)]
217e2e9c0cSopenharmony_ci#[allow(dead_code)]
227e2e9c0cSopenharmony_ci#[deny(unused_variables)]
237e2e9c0cSopenharmony_cienum Void {}
247e2e9c0cSopenharmony_ci
257e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
267e2e9c0cSopenharmony_cistruct NamedUnit;
277e2e9c0cSopenharmony_ci
287e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
297e2e9c0cSopenharmony_cistruct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
307e2e9c0cSopenharmony_ci
317e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
327e2e9c0cSopenharmony_cistruct DeNamedTuple<A, B, C>(A, B, C);
337e2e9c0cSopenharmony_ci
347e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
357e2e9c0cSopenharmony_cistruct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
367e2e9c0cSopenharmony_ci    a: &'a A,
377e2e9c0cSopenharmony_ci    b: &'b mut B,
387e2e9c0cSopenharmony_ci    c: C,
397e2e9c0cSopenharmony_ci}
407e2e9c0cSopenharmony_ci
417e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Deserialize)]
427e2e9c0cSopenharmony_cistruct DeNamedMap<A, B, C> {
437e2e9c0cSopenharmony_ci    a: A,
447e2e9c0cSopenharmony_ci    b: B,
457e2e9c0cSopenharmony_ci    c: C,
467e2e9c0cSopenharmony_ci}
477e2e9c0cSopenharmony_ci
487e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize)]
497e2e9c0cSopenharmony_cienum SerEnum<'a, B: 'a, C: 'a, D>
507e2e9c0cSopenharmony_ciwhere
517e2e9c0cSopenharmony_ci    D: 'a,
527e2e9c0cSopenharmony_ci{
537e2e9c0cSopenharmony_ci    Unit,
547e2e9c0cSopenharmony_ci    Seq(i8, B, &'a C, &'a mut D),
557e2e9c0cSopenharmony_ci    Map { a: i8, b: B, c: &'a C, d: &'a mut D },
567e2e9c0cSopenharmony_ci
577e2e9c0cSopenharmony_ci    // Make sure we can support more than one variant.
587e2e9c0cSopenharmony_ci    _Unit2,
597e2e9c0cSopenharmony_ci    _Seq2(i8, B, &'a C, &'a mut D),
607e2e9c0cSopenharmony_ci    _Map2 { a: i8, b: B, c: &'a C, d: &'a mut D },
617e2e9c0cSopenharmony_ci}
627e2e9c0cSopenharmony_ci
637e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
647e2e9c0cSopenharmony_cienum DeEnum<B, C, D> {
657e2e9c0cSopenharmony_ci    Unit,
667e2e9c0cSopenharmony_ci    Seq(i8, B, C, D),
677e2e9c0cSopenharmony_ci    Map { a: i8, b: B, c: C, d: D },
687e2e9c0cSopenharmony_ci
697e2e9c0cSopenharmony_ci    // Make sure we can support more than one variant.
707e2e9c0cSopenharmony_ci    _Unit2,
717e2e9c0cSopenharmony_ci    _Seq2(i8, B, C, D),
727e2e9c0cSopenharmony_ci    _Map2 { a: i8, b: B, c: C, d: D },
737e2e9c0cSopenharmony_ci}
747e2e9c0cSopenharmony_ci
757e2e9c0cSopenharmony_ci#[derive(Serialize)]
767e2e9c0cSopenharmony_cienum Lifetimes<'a> {
777e2e9c0cSopenharmony_ci    LifetimeSeq(&'a i32),
787e2e9c0cSopenharmony_ci    NoLifetimeSeq(i32),
797e2e9c0cSopenharmony_ci    LifetimeMap { a: &'a i32 },
807e2e9c0cSopenharmony_ci    NoLifetimeMap { a: i32 },
817e2e9c0cSopenharmony_ci}
827e2e9c0cSopenharmony_ci
837e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
847e2e9c0cSopenharmony_cipub struct GenericStruct<T> {
857e2e9c0cSopenharmony_ci    x: T,
867e2e9c0cSopenharmony_ci}
877e2e9c0cSopenharmony_ci
887e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
897e2e9c0cSopenharmony_cipub struct GenericNewTypeStruct<T>(T);
907e2e9c0cSopenharmony_ci
917e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
927e2e9c0cSopenharmony_cipub struct GenericTupleStruct<T, U>(T, U);
937e2e9c0cSopenharmony_ci
947e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
957e2e9c0cSopenharmony_cipub enum GenericEnum<T, U> {
967e2e9c0cSopenharmony_ci    Unit,
977e2e9c0cSopenharmony_ci    NewType(T),
987e2e9c0cSopenharmony_ci    Seq(T, U),
997e2e9c0cSopenharmony_ci    Map { x: T, y: U },
1007e2e9c0cSopenharmony_ci}
1017e2e9c0cSopenharmony_ci
1027e2e9c0cSopenharmony_citrait AssociatedType {
1037e2e9c0cSopenharmony_ci    type X;
1047e2e9c0cSopenharmony_ci}
1057e2e9c0cSopenharmony_ci
1067e2e9c0cSopenharmony_ciimpl AssociatedType for i32 {
1077e2e9c0cSopenharmony_ci    type X = i32;
1087e2e9c0cSopenharmony_ci}
1097e2e9c0cSopenharmony_ci
1107e2e9c0cSopenharmony_ci#[derive(Debug, PartialEq, Serialize, Deserialize)]
1117e2e9c0cSopenharmony_cistruct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
1127e2e9c0cSopenharmony_ci    phantom: PhantomData<T>,
1137e2e9c0cSopenharmony_ci}
1147e2e9c0cSopenharmony_ci
1157e2e9c0cSopenharmony_ci#[test]
1167e2e9c0cSopenharmony_cifn test_named_unit() {
1177e2e9c0cSopenharmony_ci    assert_tokens(&NamedUnit, &[Token::UnitStruct { name: "NamedUnit" }]);
1187e2e9c0cSopenharmony_ci}
1197e2e9c0cSopenharmony_ci
1207e2e9c0cSopenharmony_ci#[test]
1217e2e9c0cSopenharmony_cifn test_ser_named_tuple() {
1227e2e9c0cSopenharmony_ci    let a = 5;
1237e2e9c0cSopenharmony_ci    let mut b = 6;
1247e2e9c0cSopenharmony_ci    let c = 7;
1257e2e9c0cSopenharmony_ci    assert_ser_tokens(
1267e2e9c0cSopenharmony_ci        &SerNamedTuple(&a, &mut b, c),
1277e2e9c0cSopenharmony_ci        &[
1287e2e9c0cSopenharmony_ci            Token::TupleStruct {
1297e2e9c0cSopenharmony_ci                name: "SerNamedTuple",
1307e2e9c0cSopenharmony_ci                len: 3,
1317e2e9c0cSopenharmony_ci            },
1327e2e9c0cSopenharmony_ci            Token::I32(5),
1337e2e9c0cSopenharmony_ci            Token::I32(6),
1347e2e9c0cSopenharmony_ci            Token::I32(7),
1357e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
1367e2e9c0cSopenharmony_ci        ],
1377e2e9c0cSopenharmony_ci    );
1387e2e9c0cSopenharmony_ci}
1397e2e9c0cSopenharmony_ci
1407e2e9c0cSopenharmony_ci#[test]
1417e2e9c0cSopenharmony_cifn test_de_named_tuple() {
1427e2e9c0cSopenharmony_ci    assert_de_tokens(
1437e2e9c0cSopenharmony_ci        &DeNamedTuple(5, 6, 7),
1447e2e9c0cSopenharmony_ci        &[
1457e2e9c0cSopenharmony_ci            Token::Seq { len: Some(3) },
1467e2e9c0cSopenharmony_ci            Token::I32(5),
1477e2e9c0cSopenharmony_ci            Token::I32(6),
1487e2e9c0cSopenharmony_ci            Token::I32(7),
1497e2e9c0cSopenharmony_ci            Token::SeqEnd,
1507e2e9c0cSopenharmony_ci        ],
1517e2e9c0cSopenharmony_ci    );
1527e2e9c0cSopenharmony_ci
1537e2e9c0cSopenharmony_ci    assert_de_tokens(
1547e2e9c0cSopenharmony_ci        &DeNamedTuple(5, 6, 7),
1557e2e9c0cSopenharmony_ci        &[
1567e2e9c0cSopenharmony_ci            Token::TupleStruct {
1577e2e9c0cSopenharmony_ci                name: "DeNamedTuple",
1587e2e9c0cSopenharmony_ci                len: 3,
1597e2e9c0cSopenharmony_ci            },
1607e2e9c0cSopenharmony_ci            Token::I32(5),
1617e2e9c0cSopenharmony_ci            Token::I32(6),
1627e2e9c0cSopenharmony_ci            Token::I32(7),
1637e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
1647e2e9c0cSopenharmony_ci        ],
1657e2e9c0cSopenharmony_ci    );
1667e2e9c0cSopenharmony_ci}
1677e2e9c0cSopenharmony_ci
1687e2e9c0cSopenharmony_ci#[test]
1697e2e9c0cSopenharmony_cifn test_ser_named_map() {
1707e2e9c0cSopenharmony_ci    let a = 5;
1717e2e9c0cSopenharmony_ci    let mut b = 6;
1727e2e9c0cSopenharmony_ci    let c = 7;
1737e2e9c0cSopenharmony_ci
1747e2e9c0cSopenharmony_ci    assert_ser_tokens(
1757e2e9c0cSopenharmony_ci        &SerNamedMap {
1767e2e9c0cSopenharmony_ci            a: &a,
1777e2e9c0cSopenharmony_ci            b: &mut b,
1787e2e9c0cSopenharmony_ci            c: c,
1797e2e9c0cSopenharmony_ci        },
1807e2e9c0cSopenharmony_ci        &[
1817e2e9c0cSopenharmony_ci            Token::Struct {
1827e2e9c0cSopenharmony_ci                name: "SerNamedMap",
1837e2e9c0cSopenharmony_ci                len: 3,
1847e2e9c0cSopenharmony_ci            },
1857e2e9c0cSopenharmony_ci            Token::Str("a"),
1867e2e9c0cSopenharmony_ci            Token::I32(5),
1877e2e9c0cSopenharmony_ci            Token::Str("b"),
1887e2e9c0cSopenharmony_ci            Token::I32(6),
1897e2e9c0cSopenharmony_ci            Token::Str("c"),
1907e2e9c0cSopenharmony_ci            Token::I32(7),
1917e2e9c0cSopenharmony_ci            Token::StructEnd,
1927e2e9c0cSopenharmony_ci        ],
1937e2e9c0cSopenharmony_ci    );
1947e2e9c0cSopenharmony_ci}
1957e2e9c0cSopenharmony_ci
1967e2e9c0cSopenharmony_ci#[test]
1977e2e9c0cSopenharmony_cifn test_de_named_map() {
1987e2e9c0cSopenharmony_ci    assert_de_tokens(
1997e2e9c0cSopenharmony_ci        &DeNamedMap { a: 5, b: 6, c: 7 },
2007e2e9c0cSopenharmony_ci        &[
2017e2e9c0cSopenharmony_ci            Token::Struct {
2027e2e9c0cSopenharmony_ci                name: "DeNamedMap",
2037e2e9c0cSopenharmony_ci                len: 3,
2047e2e9c0cSopenharmony_ci            },
2057e2e9c0cSopenharmony_ci            Token::Str("a"),
2067e2e9c0cSopenharmony_ci            Token::I32(5),
2077e2e9c0cSopenharmony_ci            Token::Str("b"),
2087e2e9c0cSopenharmony_ci            Token::I32(6),
2097e2e9c0cSopenharmony_ci            Token::Str("c"),
2107e2e9c0cSopenharmony_ci            Token::I32(7),
2117e2e9c0cSopenharmony_ci            Token::StructEnd,
2127e2e9c0cSopenharmony_ci        ],
2137e2e9c0cSopenharmony_ci    );
2147e2e9c0cSopenharmony_ci}
2157e2e9c0cSopenharmony_ci
2167e2e9c0cSopenharmony_ci#[test]
2177e2e9c0cSopenharmony_cifn test_ser_enum_unit() {
2187e2e9c0cSopenharmony_ci    assert_ser_tokens(
2197e2e9c0cSopenharmony_ci        &SerEnum::Unit::<u32, u32, u32>,
2207e2e9c0cSopenharmony_ci        &[Token::UnitVariant {
2217e2e9c0cSopenharmony_ci            name: "SerEnum",
2227e2e9c0cSopenharmony_ci            variant: "Unit",
2237e2e9c0cSopenharmony_ci        }],
2247e2e9c0cSopenharmony_ci    );
2257e2e9c0cSopenharmony_ci}
2267e2e9c0cSopenharmony_ci
2277e2e9c0cSopenharmony_ci#[test]
2287e2e9c0cSopenharmony_cifn test_ser_enum_seq() {
2297e2e9c0cSopenharmony_ci    let a = 1;
2307e2e9c0cSopenharmony_ci    let b = 2;
2317e2e9c0cSopenharmony_ci    let c = 3;
2327e2e9c0cSopenharmony_ci    let mut d = 4;
2337e2e9c0cSopenharmony_ci
2347e2e9c0cSopenharmony_ci    assert_ser_tokens(
2357e2e9c0cSopenharmony_ci        &SerEnum::Seq(a, b, &c, &mut d),
2367e2e9c0cSopenharmony_ci        &[
2377e2e9c0cSopenharmony_ci            Token::TupleVariant {
2387e2e9c0cSopenharmony_ci                name: "SerEnum",
2397e2e9c0cSopenharmony_ci                variant: "Seq",
2407e2e9c0cSopenharmony_ci                len: 4,
2417e2e9c0cSopenharmony_ci            },
2427e2e9c0cSopenharmony_ci            Token::I8(1),
2437e2e9c0cSopenharmony_ci            Token::I32(2),
2447e2e9c0cSopenharmony_ci            Token::I32(3),
2457e2e9c0cSopenharmony_ci            Token::I32(4),
2467e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
2477e2e9c0cSopenharmony_ci        ],
2487e2e9c0cSopenharmony_ci    );
2497e2e9c0cSopenharmony_ci}
2507e2e9c0cSopenharmony_ci
2517e2e9c0cSopenharmony_ci#[test]
2527e2e9c0cSopenharmony_cifn test_ser_enum_map() {
2537e2e9c0cSopenharmony_ci    let a = 1;
2547e2e9c0cSopenharmony_ci    let b = 2;
2557e2e9c0cSopenharmony_ci    let c = 3;
2567e2e9c0cSopenharmony_ci    let mut d = 4;
2577e2e9c0cSopenharmony_ci
2587e2e9c0cSopenharmony_ci    assert_ser_tokens(
2597e2e9c0cSopenharmony_ci        &SerEnum::Map {
2607e2e9c0cSopenharmony_ci            a: a,
2617e2e9c0cSopenharmony_ci            b: b,
2627e2e9c0cSopenharmony_ci            c: &c,
2637e2e9c0cSopenharmony_ci            d: &mut d,
2647e2e9c0cSopenharmony_ci        },
2657e2e9c0cSopenharmony_ci        &[
2667e2e9c0cSopenharmony_ci            Token::StructVariant {
2677e2e9c0cSopenharmony_ci                name: "SerEnum",
2687e2e9c0cSopenharmony_ci                variant: "Map",
2697e2e9c0cSopenharmony_ci                len: 4,
2707e2e9c0cSopenharmony_ci            },
2717e2e9c0cSopenharmony_ci            Token::Str("a"),
2727e2e9c0cSopenharmony_ci            Token::I8(1),
2737e2e9c0cSopenharmony_ci            Token::Str("b"),
2747e2e9c0cSopenharmony_ci            Token::I32(2),
2757e2e9c0cSopenharmony_ci            Token::Str("c"),
2767e2e9c0cSopenharmony_ci            Token::I32(3),
2777e2e9c0cSopenharmony_ci            Token::Str("d"),
2787e2e9c0cSopenharmony_ci            Token::I32(4),
2797e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
2807e2e9c0cSopenharmony_ci        ],
2817e2e9c0cSopenharmony_ci    );
2827e2e9c0cSopenharmony_ci}
2837e2e9c0cSopenharmony_ci
2847e2e9c0cSopenharmony_ci#[test]
2857e2e9c0cSopenharmony_cifn test_de_enum_unit() {
2867e2e9c0cSopenharmony_ci    assert_tokens(
2877e2e9c0cSopenharmony_ci        &DeEnum::Unit::<u32, u32, u32>,
2887e2e9c0cSopenharmony_ci        &[Token::UnitVariant {
2897e2e9c0cSopenharmony_ci            name: "DeEnum",
2907e2e9c0cSopenharmony_ci            variant: "Unit",
2917e2e9c0cSopenharmony_ci        }],
2927e2e9c0cSopenharmony_ci    );
2937e2e9c0cSopenharmony_ci}
2947e2e9c0cSopenharmony_ci
2957e2e9c0cSopenharmony_ci#[test]
2967e2e9c0cSopenharmony_cifn test_de_enum_seq() {
2977e2e9c0cSopenharmony_ci    let a = 1;
2987e2e9c0cSopenharmony_ci    let b = 2;
2997e2e9c0cSopenharmony_ci    let c = 3;
3007e2e9c0cSopenharmony_ci    let d = 4;
3017e2e9c0cSopenharmony_ci
3027e2e9c0cSopenharmony_ci    assert_tokens(
3037e2e9c0cSopenharmony_ci        &DeEnum::Seq(a, b, c, d),
3047e2e9c0cSopenharmony_ci        &[
3057e2e9c0cSopenharmony_ci            Token::TupleVariant {
3067e2e9c0cSopenharmony_ci                name: "DeEnum",
3077e2e9c0cSopenharmony_ci                variant: "Seq",
3087e2e9c0cSopenharmony_ci                len: 4,
3097e2e9c0cSopenharmony_ci            },
3107e2e9c0cSopenharmony_ci            Token::I8(1),
3117e2e9c0cSopenharmony_ci            Token::I32(2),
3127e2e9c0cSopenharmony_ci            Token::I32(3),
3137e2e9c0cSopenharmony_ci            Token::I32(4),
3147e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
3157e2e9c0cSopenharmony_ci        ],
3167e2e9c0cSopenharmony_ci    );
3177e2e9c0cSopenharmony_ci}
3187e2e9c0cSopenharmony_ci
3197e2e9c0cSopenharmony_ci#[test]
3207e2e9c0cSopenharmony_cifn test_de_enum_map() {
3217e2e9c0cSopenharmony_ci    let a = 1;
3227e2e9c0cSopenharmony_ci    let b = 2;
3237e2e9c0cSopenharmony_ci    let c = 3;
3247e2e9c0cSopenharmony_ci    let d = 4;
3257e2e9c0cSopenharmony_ci
3267e2e9c0cSopenharmony_ci    assert_tokens(
3277e2e9c0cSopenharmony_ci        &DeEnum::Map {
3287e2e9c0cSopenharmony_ci            a: a,
3297e2e9c0cSopenharmony_ci            b: b,
3307e2e9c0cSopenharmony_ci            c: c,
3317e2e9c0cSopenharmony_ci            d: d,
3327e2e9c0cSopenharmony_ci        },
3337e2e9c0cSopenharmony_ci        &[
3347e2e9c0cSopenharmony_ci            Token::StructVariant {
3357e2e9c0cSopenharmony_ci                name: "DeEnum",
3367e2e9c0cSopenharmony_ci                variant: "Map",
3377e2e9c0cSopenharmony_ci                len: 4,
3387e2e9c0cSopenharmony_ci            },
3397e2e9c0cSopenharmony_ci            Token::Str("a"),
3407e2e9c0cSopenharmony_ci            Token::I8(1),
3417e2e9c0cSopenharmony_ci            Token::Str("b"),
3427e2e9c0cSopenharmony_ci            Token::I32(2),
3437e2e9c0cSopenharmony_ci            Token::Str("c"),
3447e2e9c0cSopenharmony_ci            Token::I32(3),
3457e2e9c0cSopenharmony_ci            Token::Str("d"),
3467e2e9c0cSopenharmony_ci            Token::I32(4),
3477e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
3487e2e9c0cSopenharmony_ci        ],
3497e2e9c0cSopenharmony_ci    );
3507e2e9c0cSopenharmony_ci}
3517e2e9c0cSopenharmony_ci
3527e2e9c0cSopenharmony_ci#[test]
3537e2e9c0cSopenharmony_cifn test_lifetimes() {
3547e2e9c0cSopenharmony_ci    let value = 5;
3557e2e9c0cSopenharmony_ci
3567e2e9c0cSopenharmony_ci    assert_ser_tokens(
3577e2e9c0cSopenharmony_ci        &Lifetimes::LifetimeSeq(&value),
3587e2e9c0cSopenharmony_ci        &[
3597e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
3607e2e9c0cSopenharmony_ci                name: "Lifetimes",
3617e2e9c0cSopenharmony_ci                variant: "LifetimeSeq",
3627e2e9c0cSopenharmony_ci            },
3637e2e9c0cSopenharmony_ci            Token::I32(5),
3647e2e9c0cSopenharmony_ci        ],
3657e2e9c0cSopenharmony_ci    );
3667e2e9c0cSopenharmony_ci
3677e2e9c0cSopenharmony_ci    assert_ser_tokens(
3687e2e9c0cSopenharmony_ci        &Lifetimes::NoLifetimeSeq(5),
3697e2e9c0cSopenharmony_ci        &[
3707e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
3717e2e9c0cSopenharmony_ci                name: "Lifetimes",
3727e2e9c0cSopenharmony_ci                variant: "NoLifetimeSeq",
3737e2e9c0cSopenharmony_ci            },
3747e2e9c0cSopenharmony_ci            Token::I32(5),
3757e2e9c0cSopenharmony_ci        ],
3767e2e9c0cSopenharmony_ci    );
3777e2e9c0cSopenharmony_ci
3787e2e9c0cSopenharmony_ci    assert_ser_tokens(
3797e2e9c0cSopenharmony_ci        &Lifetimes::LifetimeMap { a: &value },
3807e2e9c0cSopenharmony_ci        &[
3817e2e9c0cSopenharmony_ci            Token::StructVariant {
3827e2e9c0cSopenharmony_ci                name: "Lifetimes",
3837e2e9c0cSopenharmony_ci                variant: "LifetimeMap",
3847e2e9c0cSopenharmony_ci                len: 1,
3857e2e9c0cSopenharmony_ci            },
3867e2e9c0cSopenharmony_ci            Token::Str("a"),
3877e2e9c0cSopenharmony_ci            Token::I32(5),
3887e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
3897e2e9c0cSopenharmony_ci        ],
3907e2e9c0cSopenharmony_ci    );
3917e2e9c0cSopenharmony_ci
3927e2e9c0cSopenharmony_ci    assert_ser_tokens(
3937e2e9c0cSopenharmony_ci        &Lifetimes::NoLifetimeMap { a: 5 },
3947e2e9c0cSopenharmony_ci        &[
3957e2e9c0cSopenharmony_ci            Token::StructVariant {
3967e2e9c0cSopenharmony_ci                name: "Lifetimes",
3977e2e9c0cSopenharmony_ci                variant: "NoLifetimeMap",
3987e2e9c0cSopenharmony_ci                len: 1,
3997e2e9c0cSopenharmony_ci            },
4007e2e9c0cSopenharmony_ci            Token::Str("a"),
4017e2e9c0cSopenharmony_ci            Token::I32(5),
4027e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
4037e2e9c0cSopenharmony_ci        ],
4047e2e9c0cSopenharmony_ci    );
4057e2e9c0cSopenharmony_ci}
4067e2e9c0cSopenharmony_ci
4077e2e9c0cSopenharmony_ci#[test]
4087e2e9c0cSopenharmony_cifn test_generic_struct() {
4097e2e9c0cSopenharmony_ci    assert_tokens(
4107e2e9c0cSopenharmony_ci        &GenericStruct { x: 5u32 },
4117e2e9c0cSopenharmony_ci        &[
4127e2e9c0cSopenharmony_ci            Token::Struct {
4137e2e9c0cSopenharmony_ci                name: "GenericStruct",
4147e2e9c0cSopenharmony_ci                len: 1,
4157e2e9c0cSopenharmony_ci            },
4167e2e9c0cSopenharmony_ci            Token::Str("x"),
4177e2e9c0cSopenharmony_ci            Token::U32(5),
4187e2e9c0cSopenharmony_ci            Token::StructEnd,
4197e2e9c0cSopenharmony_ci        ],
4207e2e9c0cSopenharmony_ci    );
4217e2e9c0cSopenharmony_ci}
4227e2e9c0cSopenharmony_ci
4237e2e9c0cSopenharmony_ci#[test]
4247e2e9c0cSopenharmony_cifn test_generic_newtype_struct() {
4257e2e9c0cSopenharmony_ci    assert_tokens(
4267e2e9c0cSopenharmony_ci        &GenericNewTypeStruct(5u32),
4277e2e9c0cSopenharmony_ci        &[
4287e2e9c0cSopenharmony_ci            Token::NewtypeStruct {
4297e2e9c0cSopenharmony_ci                name: "GenericNewTypeStruct",
4307e2e9c0cSopenharmony_ci            },
4317e2e9c0cSopenharmony_ci            Token::U32(5),
4327e2e9c0cSopenharmony_ci        ],
4337e2e9c0cSopenharmony_ci    );
4347e2e9c0cSopenharmony_ci}
4357e2e9c0cSopenharmony_ci
4367e2e9c0cSopenharmony_ci#[test]
4377e2e9c0cSopenharmony_cifn test_untagged_newtype_struct() {
4387e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
4397e2e9c0cSopenharmony_ci    #[serde(untagged)]
4407e2e9c0cSopenharmony_ci    enum E {
4417e2e9c0cSopenharmony_ci        Newtype(GenericNewTypeStruct<u32>),
4427e2e9c0cSopenharmony_ci        Null,
4437e2e9c0cSopenharmony_ci    }
4447e2e9c0cSopenharmony_ci
4457e2e9c0cSopenharmony_ci    assert_tokens(
4467e2e9c0cSopenharmony_ci        &E::Newtype(GenericNewTypeStruct(5u32)),
4477e2e9c0cSopenharmony_ci        &[
4487e2e9c0cSopenharmony_ci            Token::NewtypeStruct {
4497e2e9c0cSopenharmony_ci                name: "GenericNewTypeStruct",
4507e2e9c0cSopenharmony_ci            },
4517e2e9c0cSopenharmony_ci            Token::U32(5),
4527e2e9c0cSopenharmony_ci        ],
4537e2e9c0cSopenharmony_ci    );
4547e2e9c0cSopenharmony_ci}
4557e2e9c0cSopenharmony_ci
4567e2e9c0cSopenharmony_ci#[test]
4577e2e9c0cSopenharmony_cifn test_adjacently_tagged_newtype_struct() {
4587e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
4597e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c")]
4607e2e9c0cSopenharmony_ci    enum E {
4617e2e9c0cSopenharmony_ci        Newtype(GenericNewTypeStruct<u32>),
4627e2e9c0cSopenharmony_ci        Null,
4637e2e9c0cSopenharmony_ci    }
4647e2e9c0cSopenharmony_ci
4657e2e9c0cSopenharmony_ci    assert_de_tokens(
4667e2e9c0cSopenharmony_ci        &E::Newtype(GenericNewTypeStruct(5u32)),
4677e2e9c0cSopenharmony_ci        &[
4687e2e9c0cSopenharmony_ci            Token::Struct { name: "E", len: 2 },
4697e2e9c0cSopenharmony_ci            Token::Str("c"),
4707e2e9c0cSopenharmony_ci            Token::NewtypeStruct {
4717e2e9c0cSopenharmony_ci                name: "GenericNewTypeStruct",
4727e2e9c0cSopenharmony_ci            },
4737e2e9c0cSopenharmony_ci            Token::U32(5),
4747e2e9c0cSopenharmony_ci            Token::Str("t"),
4757e2e9c0cSopenharmony_ci            Token::UnitVariant {
4767e2e9c0cSopenharmony_ci                name: "E",
4777e2e9c0cSopenharmony_ci                variant: "Newtype",
4787e2e9c0cSopenharmony_ci            },
4797e2e9c0cSopenharmony_ci            Token::StructEnd,
4807e2e9c0cSopenharmony_ci        ],
4817e2e9c0cSopenharmony_ci    );
4827e2e9c0cSopenharmony_ci}
4837e2e9c0cSopenharmony_ci
4847e2e9c0cSopenharmony_ci#[test]
4857e2e9c0cSopenharmony_cifn test_generic_tuple_struct() {
4867e2e9c0cSopenharmony_ci    assert_tokens(
4877e2e9c0cSopenharmony_ci        &GenericTupleStruct(5u32, 6u32),
4887e2e9c0cSopenharmony_ci        &[
4897e2e9c0cSopenharmony_ci            Token::TupleStruct {
4907e2e9c0cSopenharmony_ci                name: "GenericTupleStruct",
4917e2e9c0cSopenharmony_ci                len: 2,
4927e2e9c0cSopenharmony_ci            },
4937e2e9c0cSopenharmony_ci            Token::U32(5),
4947e2e9c0cSopenharmony_ci            Token::U32(6),
4957e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
4967e2e9c0cSopenharmony_ci        ],
4977e2e9c0cSopenharmony_ci    );
4987e2e9c0cSopenharmony_ci}
4997e2e9c0cSopenharmony_ci
5007e2e9c0cSopenharmony_ci#[test]
5017e2e9c0cSopenharmony_cifn test_generic_enum_unit() {
5027e2e9c0cSopenharmony_ci    assert_tokens(
5037e2e9c0cSopenharmony_ci        &GenericEnum::Unit::<u32, u32>,
5047e2e9c0cSopenharmony_ci        &[Token::UnitVariant {
5057e2e9c0cSopenharmony_ci            name: "GenericEnum",
5067e2e9c0cSopenharmony_ci            variant: "Unit",
5077e2e9c0cSopenharmony_ci        }],
5087e2e9c0cSopenharmony_ci    );
5097e2e9c0cSopenharmony_ci}
5107e2e9c0cSopenharmony_ci
5117e2e9c0cSopenharmony_ci#[test]
5127e2e9c0cSopenharmony_cifn test_generic_enum_newtype() {
5137e2e9c0cSopenharmony_ci    assert_tokens(
5147e2e9c0cSopenharmony_ci        &GenericEnum::NewType::<u32, u32>(5),
5157e2e9c0cSopenharmony_ci        &[
5167e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
5177e2e9c0cSopenharmony_ci                name: "GenericEnum",
5187e2e9c0cSopenharmony_ci                variant: "NewType",
5197e2e9c0cSopenharmony_ci            },
5207e2e9c0cSopenharmony_ci            Token::U32(5),
5217e2e9c0cSopenharmony_ci        ],
5227e2e9c0cSopenharmony_ci    );
5237e2e9c0cSopenharmony_ci}
5247e2e9c0cSopenharmony_ci
5257e2e9c0cSopenharmony_ci#[test]
5267e2e9c0cSopenharmony_cifn test_generic_enum_seq() {
5277e2e9c0cSopenharmony_ci    assert_tokens(
5287e2e9c0cSopenharmony_ci        &GenericEnum::Seq::<u32, u32>(5, 6),
5297e2e9c0cSopenharmony_ci        &[
5307e2e9c0cSopenharmony_ci            Token::TupleVariant {
5317e2e9c0cSopenharmony_ci                name: "GenericEnum",
5327e2e9c0cSopenharmony_ci                variant: "Seq",
5337e2e9c0cSopenharmony_ci                len: 2,
5347e2e9c0cSopenharmony_ci            },
5357e2e9c0cSopenharmony_ci            Token::U32(5),
5367e2e9c0cSopenharmony_ci            Token::U32(6),
5377e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
5387e2e9c0cSopenharmony_ci        ],
5397e2e9c0cSopenharmony_ci    );
5407e2e9c0cSopenharmony_ci}
5417e2e9c0cSopenharmony_ci
5427e2e9c0cSopenharmony_ci#[test]
5437e2e9c0cSopenharmony_cifn test_generic_enum_map() {
5447e2e9c0cSopenharmony_ci    assert_tokens(
5457e2e9c0cSopenharmony_ci        &GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
5467e2e9c0cSopenharmony_ci        &[
5477e2e9c0cSopenharmony_ci            Token::StructVariant {
5487e2e9c0cSopenharmony_ci                name: "GenericEnum",
5497e2e9c0cSopenharmony_ci                variant: "Map",
5507e2e9c0cSopenharmony_ci                len: 2,
5517e2e9c0cSopenharmony_ci            },
5527e2e9c0cSopenharmony_ci            Token::Str("x"),
5537e2e9c0cSopenharmony_ci            Token::U32(5),
5547e2e9c0cSopenharmony_ci            Token::Str("y"),
5557e2e9c0cSopenharmony_ci            Token::U32(6),
5567e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
5577e2e9c0cSopenharmony_ci        ],
5587e2e9c0cSopenharmony_ci    );
5597e2e9c0cSopenharmony_ci}
5607e2e9c0cSopenharmony_ci
5617e2e9c0cSopenharmony_ci#[test]
5627e2e9c0cSopenharmony_cifn test_default_ty_param() {
5637e2e9c0cSopenharmony_ci    assert_tokens(
5647e2e9c0cSopenharmony_ci        &DefaultTyParam::<i32> {
5657e2e9c0cSopenharmony_ci            phantom: PhantomData,
5667e2e9c0cSopenharmony_ci        },
5677e2e9c0cSopenharmony_ci        &[
5687e2e9c0cSopenharmony_ci            Token::Struct {
5697e2e9c0cSopenharmony_ci                name: "DefaultTyParam",
5707e2e9c0cSopenharmony_ci                len: 1,
5717e2e9c0cSopenharmony_ci            },
5727e2e9c0cSopenharmony_ci            Token::Str("phantom"),
5737e2e9c0cSopenharmony_ci            Token::UnitStruct {
5747e2e9c0cSopenharmony_ci                name: "PhantomData",
5757e2e9c0cSopenharmony_ci            },
5767e2e9c0cSopenharmony_ci            Token::StructEnd,
5777e2e9c0cSopenharmony_ci        ],
5787e2e9c0cSopenharmony_ci    );
5797e2e9c0cSopenharmony_ci}
5807e2e9c0cSopenharmony_ci
5817e2e9c0cSopenharmony_ci#[test]
5827e2e9c0cSopenharmony_cifn test_enum_state_field() {
5837e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
5847e2e9c0cSopenharmony_ci    enum SomeEnum {
5857e2e9c0cSopenharmony_ci        Key { key: char, state: bool },
5867e2e9c0cSopenharmony_ci    }
5877e2e9c0cSopenharmony_ci
5887e2e9c0cSopenharmony_ci    assert_tokens(
5897e2e9c0cSopenharmony_ci        &SomeEnum::Key {
5907e2e9c0cSopenharmony_ci            key: 'a',
5917e2e9c0cSopenharmony_ci            state: true,
5927e2e9c0cSopenharmony_ci        },
5937e2e9c0cSopenharmony_ci        &[
5947e2e9c0cSopenharmony_ci            Token::StructVariant {
5957e2e9c0cSopenharmony_ci                name: "SomeEnum",
5967e2e9c0cSopenharmony_ci                variant: "Key",
5977e2e9c0cSopenharmony_ci                len: 2,
5987e2e9c0cSopenharmony_ci            },
5997e2e9c0cSopenharmony_ci            Token::Str("key"),
6007e2e9c0cSopenharmony_ci            Token::Char('a'),
6017e2e9c0cSopenharmony_ci            Token::Str("state"),
6027e2e9c0cSopenharmony_ci            Token::Bool(true),
6037e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
6047e2e9c0cSopenharmony_ci        ],
6057e2e9c0cSopenharmony_ci    );
6067e2e9c0cSopenharmony_ci}
6077e2e9c0cSopenharmony_ci
6087e2e9c0cSopenharmony_ci#[test]
6097e2e9c0cSopenharmony_cifn test_untagged_enum() {
6107e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
6117e2e9c0cSopenharmony_ci    #[serde(untagged)]
6127e2e9c0cSopenharmony_ci    enum Untagged {
6137e2e9c0cSopenharmony_ci        A { a: u8 },
6147e2e9c0cSopenharmony_ci        B { b: u8 },
6157e2e9c0cSopenharmony_ci        C,
6167e2e9c0cSopenharmony_ci        D(u8),
6177e2e9c0cSopenharmony_ci        E(String),
6187e2e9c0cSopenharmony_ci        F(u8, u8),
6197e2e9c0cSopenharmony_ci    }
6207e2e9c0cSopenharmony_ci
6217e2e9c0cSopenharmony_ci    assert_tokens(
6227e2e9c0cSopenharmony_ci        &Untagged::A { a: 1 },
6237e2e9c0cSopenharmony_ci        &[
6247e2e9c0cSopenharmony_ci            Token::Struct {
6257e2e9c0cSopenharmony_ci                name: "Untagged",
6267e2e9c0cSopenharmony_ci                len: 1,
6277e2e9c0cSopenharmony_ci            },
6287e2e9c0cSopenharmony_ci            Token::Str("a"),
6297e2e9c0cSopenharmony_ci            Token::U8(1),
6307e2e9c0cSopenharmony_ci            Token::StructEnd,
6317e2e9c0cSopenharmony_ci        ],
6327e2e9c0cSopenharmony_ci    );
6337e2e9c0cSopenharmony_ci
6347e2e9c0cSopenharmony_ci    assert_tokens(
6357e2e9c0cSopenharmony_ci        &Untagged::B { b: 2 },
6367e2e9c0cSopenharmony_ci        &[
6377e2e9c0cSopenharmony_ci            Token::Struct {
6387e2e9c0cSopenharmony_ci                name: "Untagged",
6397e2e9c0cSopenharmony_ci                len: 1,
6407e2e9c0cSopenharmony_ci            },
6417e2e9c0cSopenharmony_ci            Token::Str("b"),
6427e2e9c0cSopenharmony_ci            Token::U8(2),
6437e2e9c0cSopenharmony_ci            Token::StructEnd,
6447e2e9c0cSopenharmony_ci        ],
6457e2e9c0cSopenharmony_ci    );
6467e2e9c0cSopenharmony_ci
6477e2e9c0cSopenharmony_ci    // Serializes to unit, deserializes from either depending on format's
6487e2e9c0cSopenharmony_ci    // preference.
6497e2e9c0cSopenharmony_ci    assert_tokens(&Untagged::C, &[Token::Unit]);
6507e2e9c0cSopenharmony_ci    assert_de_tokens(&Untagged::C, &[Token::None]);
6517e2e9c0cSopenharmony_ci
6527e2e9c0cSopenharmony_ci    assert_tokens(&Untagged::D(4), &[Token::U8(4)]);
6537e2e9c0cSopenharmony_ci    assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]);
6547e2e9c0cSopenharmony_ci
6557e2e9c0cSopenharmony_ci    assert_tokens(
6567e2e9c0cSopenharmony_ci        &Untagged::F(1, 2),
6577e2e9c0cSopenharmony_ci        &[
6587e2e9c0cSopenharmony_ci            Token::Tuple { len: 2 },
6597e2e9c0cSopenharmony_ci            Token::U8(1),
6607e2e9c0cSopenharmony_ci            Token::U8(2),
6617e2e9c0cSopenharmony_ci            Token::TupleEnd,
6627e2e9c0cSopenharmony_ci        ],
6637e2e9c0cSopenharmony_ci    );
6647e2e9c0cSopenharmony_ci
6657e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Untagged>(
6667e2e9c0cSopenharmony_ci        &[Token::Tuple { len: 1 }, Token::U8(1), Token::TupleEnd],
6677e2e9c0cSopenharmony_ci        "data did not match any variant of untagged enum Untagged",
6687e2e9c0cSopenharmony_ci    );
6697e2e9c0cSopenharmony_ci
6707e2e9c0cSopenharmony_ci    assert_de_tokens_error::<Untagged>(
6717e2e9c0cSopenharmony_ci        &[
6727e2e9c0cSopenharmony_ci            Token::Tuple { len: 3 },
6737e2e9c0cSopenharmony_ci            Token::U8(1),
6747e2e9c0cSopenharmony_ci            Token::U8(2),
6757e2e9c0cSopenharmony_ci            Token::U8(3),
6767e2e9c0cSopenharmony_ci            Token::TupleEnd,
6777e2e9c0cSopenharmony_ci        ],
6787e2e9c0cSopenharmony_ci        "data did not match any variant of untagged enum Untagged",
6797e2e9c0cSopenharmony_ci    );
6807e2e9c0cSopenharmony_ci}
6817e2e9c0cSopenharmony_ci
6827e2e9c0cSopenharmony_ci#[test]
6837e2e9c0cSopenharmony_cifn test_internally_tagged_enum() {
6847e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
6857e2e9c0cSopenharmony_ci    struct Newtype(BTreeMap<String, String>);
6867e2e9c0cSopenharmony_ci
6877e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
6887e2e9c0cSopenharmony_ci    struct Struct {
6897e2e9c0cSopenharmony_ci        f: u8,
6907e2e9c0cSopenharmony_ci    }
6917e2e9c0cSopenharmony_ci
6927e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
6937e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
6947e2e9c0cSopenharmony_ci    enum InternallyTagged {
6957e2e9c0cSopenharmony_ci        A { a: u8 },
6967e2e9c0cSopenharmony_ci        B,
6977e2e9c0cSopenharmony_ci        C(BTreeMap<String, String>),
6987e2e9c0cSopenharmony_ci        D(Newtype),
6997e2e9c0cSopenharmony_ci        E(Struct),
7007e2e9c0cSopenharmony_ci    }
7017e2e9c0cSopenharmony_ci
7027e2e9c0cSopenharmony_ci    assert_tokens(
7037e2e9c0cSopenharmony_ci        &InternallyTagged::A { a: 1 },
7047e2e9c0cSopenharmony_ci        &[
7057e2e9c0cSopenharmony_ci            Token::Struct {
7067e2e9c0cSopenharmony_ci                name: "InternallyTagged",
7077e2e9c0cSopenharmony_ci                len: 2,
7087e2e9c0cSopenharmony_ci            },
7097e2e9c0cSopenharmony_ci            Token::Str("type"),
7107e2e9c0cSopenharmony_ci            Token::Str("A"),
7117e2e9c0cSopenharmony_ci            Token::Str("a"),
7127e2e9c0cSopenharmony_ci            Token::U8(1),
7137e2e9c0cSopenharmony_ci            Token::StructEnd,
7147e2e9c0cSopenharmony_ci        ],
7157e2e9c0cSopenharmony_ci    );
7167e2e9c0cSopenharmony_ci
7177e2e9c0cSopenharmony_ci    assert_de_tokens(
7187e2e9c0cSopenharmony_ci        &InternallyTagged::A { a: 1 },
7197e2e9c0cSopenharmony_ci        &[
7207e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
7217e2e9c0cSopenharmony_ci            Token::Str("A"),
7227e2e9c0cSopenharmony_ci            Token::U8(1),
7237e2e9c0cSopenharmony_ci            Token::SeqEnd,
7247e2e9c0cSopenharmony_ci        ],
7257e2e9c0cSopenharmony_ci    );
7267e2e9c0cSopenharmony_ci
7277e2e9c0cSopenharmony_ci    assert_tokens(
7287e2e9c0cSopenharmony_ci        &InternallyTagged::B,
7297e2e9c0cSopenharmony_ci        &[
7307e2e9c0cSopenharmony_ci            Token::Struct {
7317e2e9c0cSopenharmony_ci                name: "InternallyTagged",
7327e2e9c0cSopenharmony_ci                len: 1,
7337e2e9c0cSopenharmony_ci            },
7347e2e9c0cSopenharmony_ci            Token::Str("type"),
7357e2e9c0cSopenharmony_ci            Token::Str("B"),
7367e2e9c0cSopenharmony_ci            Token::StructEnd,
7377e2e9c0cSopenharmony_ci        ],
7387e2e9c0cSopenharmony_ci    );
7397e2e9c0cSopenharmony_ci
7407e2e9c0cSopenharmony_ci    assert_de_tokens(
7417e2e9c0cSopenharmony_ci        &InternallyTagged::B,
7427e2e9c0cSopenharmony_ci        &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd],
7437e2e9c0cSopenharmony_ci    );
7447e2e9c0cSopenharmony_ci
7457e2e9c0cSopenharmony_ci    assert_tokens(
7467e2e9c0cSopenharmony_ci        &InternallyTagged::C(BTreeMap::new()),
7477e2e9c0cSopenharmony_ci        &[
7487e2e9c0cSopenharmony_ci            Token::Map { len: Some(1) },
7497e2e9c0cSopenharmony_ci            Token::Str("type"),
7507e2e9c0cSopenharmony_ci            Token::Str("C"),
7517e2e9c0cSopenharmony_ci            Token::MapEnd,
7527e2e9c0cSopenharmony_ci        ],
7537e2e9c0cSopenharmony_ci    );
7547e2e9c0cSopenharmony_ci
7557e2e9c0cSopenharmony_ci    assert_de_tokens_error::<InternallyTagged>(
7567e2e9c0cSopenharmony_ci        &[
7577e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
7587e2e9c0cSopenharmony_ci            Token::Str("C"),
7597e2e9c0cSopenharmony_ci            Token::Map { len: Some(0) },
7607e2e9c0cSopenharmony_ci            Token::MapEnd,
7617e2e9c0cSopenharmony_ci            Token::SeqEnd,
7627e2e9c0cSopenharmony_ci        ],
7637e2e9c0cSopenharmony_ci        "invalid type: sequence, expected a map",
7647e2e9c0cSopenharmony_ci    );
7657e2e9c0cSopenharmony_ci
7667e2e9c0cSopenharmony_ci    assert_tokens(
7677e2e9c0cSopenharmony_ci        &InternallyTagged::D(Newtype(BTreeMap::new())),
7687e2e9c0cSopenharmony_ci        &[
7697e2e9c0cSopenharmony_ci            Token::Map { len: Some(1) },
7707e2e9c0cSopenharmony_ci            Token::Str("type"),
7717e2e9c0cSopenharmony_ci            Token::Str("D"),
7727e2e9c0cSopenharmony_ci            Token::MapEnd,
7737e2e9c0cSopenharmony_ci        ],
7747e2e9c0cSopenharmony_ci    );
7757e2e9c0cSopenharmony_ci
7767e2e9c0cSopenharmony_ci    assert_tokens(
7777e2e9c0cSopenharmony_ci        &InternallyTagged::E(Struct { f: 6 }),
7787e2e9c0cSopenharmony_ci        &[
7797e2e9c0cSopenharmony_ci            Token::Struct {
7807e2e9c0cSopenharmony_ci                name: "Struct",
7817e2e9c0cSopenharmony_ci                len: 2,
7827e2e9c0cSopenharmony_ci            },
7837e2e9c0cSopenharmony_ci            Token::Str("type"),
7847e2e9c0cSopenharmony_ci            Token::Str("E"),
7857e2e9c0cSopenharmony_ci            Token::Str("f"),
7867e2e9c0cSopenharmony_ci            Token::U8(6),
7877e2e9c0cSopenharmony_ci            Token::StructEnd,
7887e2e9c0cSopenharmony_ci        ],
7897e2e9c0cSopenharmony_ci    );
7907e2e9c0cSopenharmony_ci
7917e2e9c0cSopenharmony_ci    assert_de_tokens(
7927e2e9c0cSopenharmony_ci        &InternallyTagged::E(Struct { f: 6 }),
7937e2e9c0cSopenharmony_ci        &[
7947e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
7957e2e9c0cSopenharmony_ci            Token::Str("E"),
7967e2e9c0cSopenharmony_ci            Token::U8(6),
7977e2e9c0cSopenharmony_ci            Token::SeqEnd,
7987e2e9c0cSopenharmony_ci        ],
7997e2e9c0cSopenharmony_ci    );
8007e2e9c0cSopenharmony_ci
8017e2e9c0cSopenharmony_ci    assert_de_tokens_error::<InternallyTagged>(
8027e2e9c0cSopenharmony_ci        &[Token::Map { len: Some(0) }, Token::MapEnd],
8037e2e9c0cSopenharmony_ci        "missing field `type`",
8047e2e9c0cSopenharmony_ci    );
8057e2e9c0cSopenharmony_ci
8067e2e9c0cSopenharmony_ci    assert_de_tokens_error::<InternallyTagged>(
8077e2e9c0cSopenharmony_ci        &[
8087e2e9c0cSopenharmony_ci            Token::Map { len: Some(1) },
8097e2e9c0cSopenharmony_ci            Token::Str("type"),
8107e2e9c0cSopenharmony_ci            Token::Str("Z"),
8117e2e9c0cSopenharmony_ci            Token::MapEnd,
8127e2e9c0cSopenharmony_ci        ],
8137e2e9c0cSopenharmony_ci        "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`",
8147e2e9c0cSopenharmony_ci    );
8157e2e9c0cSopenharmony_ci}
8167e2e9c0cSopenharmony_ci
8177e2e9c0cSopenharmony_ci#[test]
8187e2e9c0cSopenharmony_cifn test_internally_tagged_enum_with_untagged_variant() {
8197e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
8207e2e9c0cSopenharmony_ci    #[serde(tag = "kind")]
8217e2e9c0cSopenharmony_ci    enum InternallyTagged {
8227e2e9c0cSopenharmony_ci        Tagged {
8237e2e9c0cSopenharmony_ci            a: u8,
8247e2e9c0cSopenharmony_ci        },
8257e2e9c0cSopenharmony_ci        #[serde(untagged)]
8267e2e9c0cSopenharmony_ci        Untagged {
8277e2e9c0cSopenharmony_ci            kind: String,
8287e2e9c0cSopenharmony_ci            b: u8,
8297e2e9c0cSopenharmony_ci        },
8307e2e9c0cSopenharmony_ci    }
8317e2e9c0cSopenharmony_ci
8327e2e9c0cSopenharmony_ci    assert_de_tokens(
8337e2e9c0cSopenharmony_ci        &InternallyTagged::Tagged { a: 1 },
8347e2e9c0cSopenharmony_ci        &[
8357e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
8367e2e9c0cSopenharmony_ci            Token::Str("kind"),
8377e2e9c0cSopenharmony_ci            Token::Str("Tagged"),
8387e2e9c0cSopenharmony_ci            Token::Str("a"),
8397e2e9c0cSopenharmony_ci            Token::U8(1),
8407e2e9c0cSopenharmony_ci            Token::MapEnd,
8417e2e9c0cSopenharmony_ci        ],
8427e2e9c0cSopenharmony_ci    );
8437e2e9c0cSopenharmony_ci
8447e2e9c0cSopenharmony_ci    assert_tokens(
8457e2e9c0cSopenharmony_ci        &InternallyTagged::Tagged { a: 1 },
8467e2e9c0cSopenharmony_ci        &[
8477e2e9c0cSopenharmony_ci            Token::Struct {
8487e2e9c0cSopenharmony_ci                name: "InternallyTagged",
8497e2e9c0cSopenharmony_ci                len: 2,
8507e2e9c0cSopenharmony_ci            },
8517e2e9c0cSopenharmony_ci            Token::Str("kind"),
8527e2e9c0cSopenharmony_ci            Token::Str("Tagged"),
8537e2e9c0cSopenharmony_ci            Token::Str("a"),
8547e2e9c0cSopenharmony_ci            Token::U8(1),
8557e2e9c0cSopenharmony_ci            Token::StructEnd,
8567e2e9c0cSopenharmony_ci        ],
8577e2e9c0cSopenharmony_ci    );
8587e2e9c0cSopenharmony_ci
8597e2e9c0cSopenharmony_ci    assert_de_tokens(
8607e2e9c0cSopenharmony_ci        &InternallyTagged::Untagged {
8617e2e9c0cSopenharmony_ci            kind: "Foo".to_owned(),
8627e2e9c0cSopenharmony_ci            b: 2,
8637e2e9c0cSopenharmony_ci        },
8647e2e9c0cSopenharmony_ci        &[
8657e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
8667e2e9c0cSopenharmony_ci            Token::Str("kind"),
8677e2e9c0cSopenharmony_ci            Token::Str("Foo"),
8687e2e9c0cSopenharmony_ci            Token::Str("b"),
8697e2e9c0cSopenharmony_ci            Token::U8(2),
8707e2e9c0cSopenharmony_ci            Token::MapEnd,
8717e2e9c0cSopenharmony_ci        ],
8727e2e9c0cSopenharmony_ci    );
8737e2e9c0cSopenharmony_ci
8747e2e9c0cSopenharmony_ci    assert_tokens(
8757e2e9c0cSopenharmony_ci        &InternallyTagged::Untagged {
8767e2e9c0cSopenharmony_ci            kind: "Foo".to_owned(),
8777e2e9c0cSopenharmony_ci            b: 2,
8787e2e9c0cSopenharmony_ci        },
8797e2e9c0cSopenharmony_ci        &[
8807e2e9c0cSopenharmony_ci            Token::Struct {
8817e2e9c0cSopenharmony_ci                name: "InternallyTagged",
8827e2e9c0cSopenharmony_ci                len: 2,
8837e2e9c0cSopenharmony_ci            },
8847e2e9c0cSopenharmony_ci            Token::Str("kind"),
8857e2e9c0cSopenharmony_ci            Token::Str("Foo"),
8867e2e9c0cSopenharmony_ci            Token::Str("b"),
8877e2e9c0cSopenharmony_ci            Token::U8(2),
8887e2e9c0cSopenharmony_ci            Token::StructEnd,
8897e2e9c0cSopenharmony_ci        ],
8907e2e9c0cSopenharmony_ci    );
8917e2e9c0cSopenharmony_ci
8927e2e9c0cSopenharmony_ci    assert_tokens(
8937e2e9c0cSopenharmony_ci        &InternallyTagged::Untagged {
8947e2e9c0cSopenharmony_ci            kind: "Tagged".to_owned(),
8957e2e9c0cSopenharmony_ci            b: 2,
8967e2e9c0cSopenharmony_ci        },
8977e2e9c0cSopenharmony_ci        &[
8987e2e9c0cSopenharmony_ci            Token::Struct {
8997e2e9c0cSopenharmony_ci                name: "InternallyTagged",
9007e2e9c0cSopenharmony_ci                len: 2,
9017e2e9c0cSopenharmony_ci            },
9027e2e9c0cSopenharmony_ci            Token::Str("kind"),
9037e2e9c0cSopenharmony_ci            Token::Str("Tagged"),
9047e2e9c0cSopenharmony_ci            Token::Str("b"),
9057e2e9c0cSopenharmony_ci            Token::U8(2),
9067e2e9c0cSopenharmony_ci            Token::StructEnd,
9077e2e9c0cSopenharmony_ci        ],
9087e2e9c0cSopenharmony_ci    );
9097e2e9c0cSopenharmony_ci}
9107e2e9c0cSopenharmony_ci
9117e2e9c0cSopenharmony_ci#[test]
9127e2e9c0cSopenharmony_cifn test_internally_tagged_bytes() {
9137e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
9147e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
9157e2e9c0cSopenharmony_ci    enum InternallyTagged {
9167e2e9c0cSopenharmony_ci        String {
9177e2e9c0cSopenharmony_ci            string: String,
9187e2e9c0cSopenharmony_ci        },
9197e2e9c0cSopenharmony_ci        Bytes {
9207e2e9c0cSopenharmony_ci            #[serde(with = "bytes")]
9217e2e9c0cSopenharmony_ci            bytes: Vec<u8>,
9227e2e9c0cSopenharmony_ci        },
9237e2e9c0cSopenharmony_ci    }
9247e2e9c0cSopenharmony_ci
9257e2e9c0cSopenharmony_ci    assert_de_tokens(
9267e2e9c0cSopenharmony_ci        &InternallyTagged::String {
9277e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
9287e2e9c0cSopenharmony_ci        },
9297e2e9c0cSopenharmony_ci        &[
9307e2e9c0cSopenharmony_ci            Token::Struct {
9317e2e9c0cSopenharmony_ci                name: "String",
9327e2e9c0cSopenharmony_ci                len: 2,
9337e2e9c0cSopenharmony_ci            },
9347e2e9c0cSopenharmony_ci            Token::Str("type"),
9357e2e9c0cSopenharmony_ci            Token::Str("String"),
9367e2e9c0cSopenharmony_ci            Token::Str("string"),
9377e2e9c0cSopenharmony_ci            Token::Str("\0"),
9387e2e9c0cSopenharmony_ci            Token::StructEnd,
9397e2e9c0cSopenharmony_ci        ],
9407e2e9c0cSopenharmony_ci    );
9417e2e9c0cSopenharmony_ci
9427e2e9c0cSopenharmony_ci    assert_de_tokens(
9437e2e9c0cSopenharmony_ci        &InternallyTagged::String {
9447e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
9457e2e9c0cSopenharmony_ci        },
9467e2e9c0cSopenharmony_ci        &[
9477e2e9c0cSopenharmony_ci            Token::Struct {
9487e2e9c0cSopenharmony_ci                name: "String",
9497e2e9c0cSopenharmony_ci                len: 2,
9507e2e9c0cSopenharmony_ci            },
9517e2e9c0cSopenharmony_ci            Token::Str("type"),
9527e2e9c0cSopenharmony_ci            Token::Str("String"),
9537e2e9c0cSopenharmony_ci            Token::Str("string"),
9547e2e9c0cSopenharmony_ci            Token::String("\0"),
9557e2e9c0cSopenharmony_ci            Token::StructEnd,
9567e2e9c0cSopenharmony_ci        ],
9577e2e9c0cSopenharmony_ci    );
9587e2e9c0cSopenharmony_ci
9597e2e9c0cSopenharmony_ci    assert_de_tokens(
9607e2e9c0cSopenharmony_ci        &InternallyTagged::String {
9617e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
9627e2e9c0cSopenharmony_ci        },
9637e2e9c0cSopenharmony_ci        &[
9647e2e9c0cSopenharmony_ci            Token::Struct {
9657e2e9c0cSopenharmony_ci                name: "String",
9667e2e9c0cSopenharmony_ci                len: 2,
9677e2e9c0cSopenharmony_ci            },
9687e2e9c0cSopenharmony_ci            Token::Str("type"),
9697e2e9c0cSopenharmony_ci            Token::Str("String"),
9707e2e9c0cSopenharmony_ci            Token::Str("string"),
9717e2e9c0cSopenharmony_ci            Token::Bytes(b"\0"),
9727e2e9c0cSopenharmony_ci            Token::StructEnd,
9737e2e9c0cSopenharmony_ci        ],
9747e2e9c0cSopenharmony_ci    );
9757e2e9c0cSopenharmony_ci
9767e2e9c0cSopenharmony_ci    assert_de_tokens(
9777e2e9c0cSopenharmony_ci        &InternallyTagged::String {
9787e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
9797e2e9c0cSopenharmony_ci        },
9807e2e9c0cSopenharmony_ci        &[
9817e2e9c0cSopenharmony_ci            Token::Struct {
9827e2e9c0cSopenharmony_ci                name: "String",
9837e2e9c0cSopenharmony_ci                len: 2,
9847e2e9c0cSopenharmony_ci            },
9857e2e9c0cSopenharmony_ci            Token::Str("type"),
9867e2e9c0cSopenharmony_ci            Token::Str("String"),
9877e2e9c0cSopenharmony_ci            Token::Str("string"),
9887e2e9c0cSopenharmony_ci            Token::ByteBuf(b"\0"),
9897e2e9c0cSopenharmony_ci            Token::StructEnd,
9907e2e9c0cSopenharmony_ci        ],
9917e2e9c0cSopenharmony_ci    );
9927e2e9c0cSopenharmony_ci
9937e2e9c0cSopenharmony_ci    assert_de_tokens(
9947e2e9c0cSopenharmony_ci        &InternallyTagged::Bytes { bytes: vec![0] },
9957e2e9c0cSopenharmony_ci        &[
9967e2e9c0cSopenharmony_ci            Token::Struct {
9977e2e9c0cSopenharmony_ci                name: "Bytes",
9987e2e9c0cSopenharmony_ci                len: 2,
9997e2e9c0cSopenharmony_ci            },
10007e2e9c0cSopenharmony_ci            Token::Str("type"),
10017e2e9c0cSopenharmony_ci            Token::Str("Bytes"),
10027e2e9c0cSopenharmony_ci            Token::Str("bytes"),
10037e2e9c0cSopenharmony_ci            Token::Str("\0"),
10047e2e9c0cSopenharmony_ci            Token::StructEnd,
10057e2e9c0cSopenharmony_ci        ],
10067e2e9c0cSopenharmony_ci    );
10077e2e9c0cSopenharmony_ci
10087e2e9c0cSopenharmony_ci    assert_de_tokens(
10097e2e9c0cSopenharmony_ci        &InternallyTagged::Bytes { bytes: vec![0] },
10107e2e9c0cSopenharmony_ci        &[
10117e2e9c0cSopenharmony_ci            Token::Struct {
10127e2e9c0cSopenharmony_ci                name: "Bytes",
10137e2e9c0cSopenharmony_ci                len: 2,
10147e2e9c0cSopenharmony_ci            },
10157e2e9c0cSopenharmony_ci            Token::Str("type"),
10167e2e9c0cSopenharmony_ci            Token::Str("Bytes"),
10177e2e9c0cSopenharmony_ci            Token::Str("bytes"),
10187e2e9c0cSopenharmony_ci            Token::String("\0"),
10197e2e9c0cSopenharmony_ci            Token::StructEnd,
10207e2e9c0cSopenharmony_ci        ],
10217e2e9c0cSopenharmony_ci    );
10227e2e9c0cSopenharmony_ci
10237e2e9c0cSopenharmony_ci    assert_de_tokens(
10247e2e9c0cSopenharmony_ci        &InternallyTagged::Bytes { bytes: vec![0] },
10257e2e9c0cSopenharmony_ci        &[
10267e2e9c0cSopenharmony_ci            Token::Struct {
10277e2e9c0cSopenharmony_ci                name: "Bytes",
10287e2e9c0cSopenharmony_ci                len: 2,
10297e2e9c0cSopenharmony_ci            },
10307e2e9c0cSopenharmony_ci            Token::Str("type"),
10317e2e9c0cSopenharmony_ci            Token::Str("Bytes"),
10327e2e9c0cSopenharmony_ci            Token::Str("bytes"),
10337e2e9c0cSopenharmony_ci            Token::Bytes(b"\0"),
10347e2e9c0cSopenharmony_ci            Token::StructEnd,
10357e2e9c0cSopenharmony_ci        ],
10367e2e9c0cSopenharmony_ci    );
10377e2e9c0cSopenharmony_ci
10387e2e9c0cSopenharmony_ci    assert_de_tokens(
10397e2e9c0cSopenharmony_ci        &InternallyTagged::Bytes { bytes: vec![0] },
10407e2e9c0cSopenharmony_ci        &[
10417e2e9c0cSopenharmony_ci            Token::Struct {
10427e2e9c0cSopenharmony_ci                name: "Bytes",
10437e2e9c0cSopenharmony_ci                len: 2,
10447e2e9c0cSopenharmony_ci            },
10457e2e9c0cSopenharmony_ci            Token::Str("type"),
10467e2e9c0cSopenharmony_ci            Token::Str("Bytes"),
10477e2e9c0cSopenharmony_ci            Token::Str("bytes"),
10487e2e9c0cSopenharmony_ci            Token::ByteBuf(b"\0"),
10497e2e9c0cSopenharmony_ci            Token::StructEnd,
10507e2e9c0cSopenharmony_ci        ],
10517e2e9c0cSopenharmony_ci    );
10527e2e9c0cSopenharmony_ci
10537e2e9c0cSopenharmony_ci    assert_de_tokens(
10547e2e9c0cSopenharmony_ci        &InternallyTagged::Bytes { bytes: vec![0] },
10557e2e9c0cSopenharmony_ci        &[
10567e2e9c0cSopenharmony_ci            Token::Struct {
10577e2e9c0cSopenharmony_ci                name: "Bytes",
10587e2e9c0cSopenharmony_ci                len: 2,
10597e2e9c0cSopenharmony_ci            },
10607e2e9c0cSopenharmony_ci            Token::Str("type"),
10617e2e9c0cSopenharmony_ci            Token::Str("Bytes"),
10627e2e9c0cSopenharmony_ci            Token::Str("bytes"),
10637e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
10647e2e9c0cSopenharmony_ci            Token::U8(0),
10657e2e9c0cSopenharmony_ci            Token::SeqEnd,
10667e2e9c0cSopenharmony_ci            Token::StructEnd,
10677e2e9c0cSopenharmony_ci        ],
10687e2e9c0cSopenharmony_ci    );
10697e2e9c0cSopenharmony_ci}
10707e2e9c0cSopenharmony_ci
10717e2e9c0cSopenharmony_ci#[test]
10727e2e9c0cSopenharmony_cifn test_internally_tagged_struct_variant_containing_unit_variant() {
10737e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
10747e2e9c0cSopenharmony_ci    pub enum Level {
10757e2e9c0cSopenharmony_ci        Info,
10767e2e9c0cSopenharmony_ci    }
10777e2e9c0cSopenharmony_ci
10787e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
10797e2e9c0cSopenharmony_ci    #[serde(tag = "action")]
10807e2e9c0cSopenharmony_ci    pub enum Message {
10817e2e9c0cSopenharmony_ci        Log { level: Level },
10827e2e9c0cSopenharmony_ci    }
10837e2e9c0cSopenharmony_ci
10847e2e9c0cSopenharmony_ci    assert_de_tokens(
10857e2e9c0cSopenharmony_ci        &Message::Log { level: Level::Info },
10867e2e9c0cSopenharmony_ci        &[
10877e2e9c0cSopenharmony_ci            Token::Struct {
10887e2e9c0cSopenharmony_ci                name: "Message",
10897e2e9c0cSopenharmony_ci                len: 2,
10907e2e9c0cSopenharmony_ci            },
10917e2e9c0cSopenharmony_ci            Token::Str("action"),
10927e2e9c0cSopenharmony_ci            Token::Str("Log"),
10937e2e9c0cSopenharmony_ci            Token::Str("level"),
10947e2e9c0cSopenharmony_ci            Token::BorrowedStr("Info"),
10957e2e9c0cSopenharmony_ci            Token::StructEnd,
10967e2e9c0cSopenharmony_ci        ],
10977e2e9c0cSopenharmony_ci    );
10987e2e9c0cSopenharmony_ci
10997e2e9c0cSopenharmony_ci    assert_de_tokens(
11007e2e9c0cSopenharmony_ci        &Message::Log { level: Level::Info },
11017e2e9c0cSopenharmony_ci        &[
11027e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
11037e2e9c0cSopenharmony_ci            Token::Str("action"),
11047e2e9c0cSopenharmony_ci            Token::Str("Log"),
11057e2e9c0cSopenharmony_ci            Token::Str("level"),
11067e2e9c0cSopenharmony_ci            Token::BorrowedStr("Info"),
11077e2e9c0cSopenharmony_ci            Token::MapEnd,
11087e2e9c0cSopenharmony_ci        ],
11097e2e9c0cSopenharmony_ci    );
11107e2e9c0cSopenharmony_ci
11117e2e9c0cSopenharmony_ci    assert_de_tokens(
11127e2e9c0cSopenharmony_ci        &Message::Log { level: Level::Info },
11137e2e9c0cSopenharmony_ci        &[
11147e2e9c0cSopenharmony_ci            Token::Seq { len: Some(2) },
11157e2e9c0cSopenharmony_ci            Token::Str("Log"),
11167e2e9c0cSopenharmony_ci            Token::BorrowedStr("Info"),
11177e2e9c0cSopenharmony_ci            Token::SeqEnd,
11187e2e9c0cSopenharmony_ci        ],
11197e2e9c0cSopenharmony_ci    );
11207e2e9c0cSopenharmony_ci}
11217e2e9c0cSopenharmony_ci
11227e2e9c0cSopenharmony_ci#[test]
11237e2e9c0cSopenharmony_cifn test_internally_tagged_borrow() {
11247e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
11257e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
11267e2e9c0cSopenharmony_ci    pub enum Input<'a> {
11277e2e9c0cSopenharmony_ci        Package { name: &'a str },
11287e2e9c0cSopenharmony_ci    }
11297e2e9c0cSopenharmony_ci
11307e2e9c0cSopenharmony_ci    assert_tokens(
11317e2e9c0cSopenharmony_ci        &Input::Package { name: "borrowed" },
11327e2e9c0cSopenharmony_ci        &[
11337e2e9c0cSopenharmony_ci            Token::Struct {
11347e2e9c0cSopenharmony_ci                name: "Input",
11357e2e9c0cSopenharmony_ci                len: 2,
11367e2e9c0cSopenharmony_ci            },
11377e2e9c0cSopenharmony_ci            Token::BorrowedStr("type"),
11387e2e9c0cSopenharmony_ci            Token::BorrowedStr("Package"),
11397e2e9c0cSopenharmony_ci            Token::BorrowedStr("name"),
11407e2e9c0cSopenharmony_ci            Token::BorrowedStr("borrowed"),
11417e2e9c0cSopenharmony_ci            Token::StructEnd,
11427e2e9c0cSopenharmony_ci        ],
11437e2e9c0cSopenharmony_ci    );
11447e2e9c0cSopenharmony_ci}
11457e2e9c0cSopenharmony_ci
11467e2e9c0cSopenharmony_ci#[test]
11477e2e9c0cSopenharmony_cifn test_adjacently_tagged_enum() {
11487e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
11497e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c")]
11507e2e9c0cSopenharmony_ci    enum AdjacentlyTagged<T> {
11517e2e9c0cSopenharmony_ci        Unit,
11527e2e9c0cSopenharmony_ci        Newtype(T),
11537e2e9c0cSopenharmony_ci        Tuple(u8, u8),
11547e2e9c0cSopenharmony_ci        Struct { f: u8 },
11557e2e9c0cSopenharmony_ci    }
11567e2e9c0cSopenharmony_ci
11577e2e9c0cSopenharmony_ci    // unit with no content
11587e2e9c0cSopenharmony_ci    assert_ser_tokens(
11597e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit::<u8>,
11607e2e9c0cSopenharmony_ci        &[
11617e2e9c0cSopenharmony_ci            Token::Struct {
11627e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
11637e2e9c0cSopenharmony_ci                len: 1,
11647e2e9c0cSopenharmony_ci            },
11657e2e9c0cSopenharmony_ci            Token::Str("t"),
11667e2e9c0cSopenharmony_ci            Token::UnitVariant {
11677e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
11687e2e9c0cSopenharmony_ci                variant: "Unit",
11697e2e9c0cSopenharmony_ci            },
11707e2e9c0cSopenharmony_ci            Token::StructEnd,
11717e2e9c0cSopenharmony_ci        ],
11727e2e9c0cSopenharmony_ci    );
11737e2e9c0cSopenharmony_ci
11747e2e9c0cSopenharmony_ci    // unit with no content
11757e2e9c0cSopenharmony_ci    assert_de_tokens(
11767e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit::<u8>,
11777e2e9c0cSopenharmony_ci        &[
11787e2e9c0cSopenharmony_ci            Token::Struct {
11797e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
11807e2e9c0cSopenharmony_ci                len: 2,
11817e2e9c0cSopenharmony_ci            },
11827e2e9c0cSopenharmony_ci            Token::Str("t"),
11837e2e9c0cSopenharmony_ci            Token::UnitVariant {
11847e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
11857e2e9c0cSopenharmony_ci                variant: "Unit",
11867e2e9c0cSopenharmony_ci            },
11877e2e9c0cSopenharmony_ci            Token::StructEnd,
11887e2e9c0cSopenharmony_ci        ],
11897e2e9c0cSopenharmony_ci    );
11907e2e9c0cSopenharmony_ci
11917e2e9c0cSopenharmony_ci    // unit with tag first
11927e2e9c0cSopenharmony_ci    assert_de_tokens(
11937e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit::<u8>,
11947e2e9c0cSopenharmony_ci        &[
11957e2e9c0cSopenharmony_ci            Token::Struct {
11967e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
11977e2e9c0cSopenharmony_ci                len: 2,
11987e2e9c0cSopenharmony_ci            },
11997e2e9c0cSopenharmony_ci            Token::Str("t"),
12007e2e9c0cSopenharmony_ci            Token::UnitVariant {
12017e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12027e2e9c0cSopenharmony_ci                variant: "Unit",
12037e2e9c0cSopenharmony_ci            },
12047e2e9c0cSopenharmony_ci            Token::Str("c"),
12057e2e9c0cSopenharmony_ci            Token::Unit,
12067e2e9c0cSopenharmony_ci            Token::StructEnd,
12077e2e9c0cSopenharmony_ci        ],
12087e2e9c0cSopenharmony_ci    );
12097e2e9c0cSopenharmony_ci
12107e2e9c0cSopenharmony_ci    // unit with content first
12117e2e9c0cSopenharmony_ci    assert_de_tokens(
12127e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit::<u8>,
12137e2e9c0cSopenharmony_ci        &[
12147e2e9c0cSopenharmony_ci            Token::Struct {
12157e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12167e2e9c0cSopenharmony_ci                len: 2,
12177e2e9c0cSopenharmony_ci            },
12187e2e9c0cSopenharmony_ci            Token::Str("c"),
12197e2e9c0cSopenharmony_ci            Token::Unit,
12207e2e9c0cSopenharmony_ci            Token::Str("t"),
12217e2e9c0cSopenharmony_ci            Token::UnitVariant {
12227e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12237e2e9c0cSopenharmony_ci                variant: "Unit",
12247e2e9c0cSopenharmony_ci            },
12257e2e9c0cSopenharmony_ci            Token::StructEnd,
12267e2e9c0cSopenharmony_ci        ],
12277e2e9c0cSopenharmony_ci    );
12287e2e9c0cSopenharmony_ci
12297e2e9c0cSopenharmony_ci    // unit with excess content (f, g, h)
12307e2e9c0cSopenharmony_ci    assert_de_tokens(
12317e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit::<u8>,
12327e2e9c0cSopenharmony_ci        &[
12337e2e9c0cSopenharmony_ci            Token::Struct {
12347e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12357e2e9c0cSopenharmony_ci                len: 2,
12367e2e9c0cSopenharmony_ci            },
12377e2e9c0cSopenharmony_ci            Token::Str("f"),
12387e2e9c0cSopenharmony_ci            Token::Unit,
12397e2e9c0cSopenharmony_ci            Token::Str("t"),
12407e2e9c0cSopenharmony_ci            Token::UnitVariant {
12417e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12427e2e9c0cSopenharmony_ci                variant: "Unit",
12437e2e9c0cSopenharmony_ci            },
12447e2e9c0cSopenharmony_ci            Token::Str("g"),
12457e2e9c0cSopenharmony_ci            Token::Unit,
12467e2e9c0cSopenharmony_ci            Token::Str("c"),
12477e2e9c0cSopenharmony_ci            Token::Unit,
12487e2e9c0cSopenharmony_ci            Token::Str("h"),
12497e2e9c0cSopenharmony_ci            Token::Unit,
12507e2e9c0cSopenharmony_ci            Token::StructEnd,
12517e2e9c0cSopenharmony_ci        ],
12527e2e9c0cSopenharmony_ci    );
12537e2e9c0cSopenharmony_ci
12547e2e9c0cSopenharmony_ci    // newtype with tag first
12557e2e9c0cSopenharmony_ci    assert_tokens(
12567e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Newtype::<u8>(1),
12577e2e9c0cSopenharmony_ci        &[
12587e2e9c0cSopenharmony_ci            Token::Struct {
12597e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12607e2e9c0cSopenharmony_ci                len: 2,
12617e2e9c0cSopenharmony_ci            },
12627e2e9c0cSopenharmony_ci            Token::Str("t"),
12637e2e9c0cSopenharmony_ci            Token::UnitVariant {
12647e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12657e2e9c0cSopenharmony_ci                variant: "Newtype",
12667e2e9c0cSopenharmony_ci            },
12677e2e9c0cSopenharmony_ci            Token::Str("c"),
12687e2e9c0cSopenharmony_ci            Token::U8(1),
12697e2e9c0cSopenharmony_ci            Token::StructEnd,
12707e2e9c0cSopenharmony_ci        ],
12717e2e9c0cSopenharmony_ci    );
12727e2e9c0cSopenharmony_ci
12737e2e9c0cSopenharmony_ci    // newtype with content first
12747e2e9c0cSopenharmony_ci    assert_de_tokens(
12757e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Newtype::<u8>(1),
12767e2e9c0cSopenharmony_ci        &[
12777e2e9c0cSopenharmony_ci            Token::Struct {
12787e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12797e2e9c0cSopenharmony_ci                len: 2,
12807e2e9c0cSopenharmony_ci            },
12817e2e9c0cSopenharmony_ci            Token::Str("c"),
12827e2e9c0cSopenharmony_ci            Token::U8(1),
12837e2e9c0cSopenharmony_ci            Token::Str("t"),
12847e2e9c0cSopenharmony_ci            Token::UnitVariant {
12857e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12867e2e9c0cSopenharmony_ci                variant: "Newtype",
12877e2e9c0cSopenharmony_ci            },
12887e2e9c0cSopenharmony_ci            Token::StructEnd,
12897e2e9c0cSopenharmony_ci        ],
12907e2e9c0cSopenharmony_ci    );
12917e2e9c0cSopenharmony_ci
12927e2e9c0cSopenharmony_ci    // optional newtype with no content field
12937e2e9c0cSopenharmony_ci    assert_de_tokens(
12947e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Newtype::<Option<u8>>(None),
12957e2e9c0cSopenharmony_ci        &[
12967e2e9c0cSopenharmony_ci            Token::Struct {
12977e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
12987e2e9c0cSopenharmony_ci                len: 1,
12997e2e9c0cSopenharmony_ci            },
13007e2e9c0cSopenharmony_ci            Token::Str("t"),
13017e2e9c0cSopenharmony_ci            Token::UnitVariant {
13027e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13037e2e9c0cSopenharmony_ci                variant: "Newtype",
13047e2e9c0cSopenharmony_ci            },
13057e2e9c0cSopenharmony_ci            Token::StructEnd,
13067e2e9c0cSopenharmony_ci        ],
13077e2e9c0cSopenharmony_ci    );
13087e2e9c0cSopenharmony_ci
13097e2e9c0cSopenharmony_ci    // tuple with tag first
13107e2e9c0cSopenharmony_ci    assert_tokens(
13117e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Tuple::<u8>(1, 1),
13127e2e9c0cSopenharmony_ci        &[
13137e2e9c0cSopenharmony_ci            Token::Struct {
13147e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13157e2e9c0cSopenharmony_ci                len: 2,
13167e2e9c0cSopenharmony_ci            },
13177e2e9c0cSopenharmony_ci            Token::Str("t"),
13187e2e9c0cSopenharmony_ci            Token::UnitVariant {
13197e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13207e2e9c0cSopenharmony_ci                variant: "Tuple",
13217e2e9c0cSopenharmony_ci            },
13227e2e9c0cSopenharmony_ci            Token::Str("c"),
13237e2e9c0cSopenharmony_ci            Token::Tuple { len: 2 },
13247e2e9c0cSopenharmony_ci            Token::U8(1),
13257e2e9c0cSopenharmony_ci            Token::U8(1),
13267e2e9c0cSopenharmony_ci            Token::TupleEnd,
13277e2e9c0cSopenharmony_ci            Token::StructEnd,
13287e2e9c0cSopenharmony_ci        ],
13297e2e9c0cSopenharmony_ci    );
13307e2e9c0cSopenharmony_ci
13317e2e9c0cSopenharmony_ci    // tuple with content first
13327e2e9c0cSopenharmony_ci    assert_de_tokens(
13337e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Tuple::<u8>(1, 1),
13347e2e9c0cSopenharmony_ci        &[
13357e2e9c0cSopenharmony_ci            Token::Struct {
13367e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13377e2e9c0cSopenharmony_ci                len: 2,
13387e2e9c0cSopenharmony_ci            },
13397e2e9c0cSopenharmony_ci            Token::Str("c"),
13407e2e9c0cSopenharmony_ci            Token::Tuple { len: 2 },
13417e2e9c0cSopenharmony_ci            Token::U8(1),
13427e2e9c0cSopenharmony_ci            Token::U8(1),
13437e2e9c0cSopenharmony_ci            Token::TupleEnd,
13447e2e9c0cSopenharmony_ci            Token::Str("t"),
13457e2e9c0cSopenharmony_ci            Token::UnitVariant {
13467e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13477e2e9c0cSopenharmony_ci                variant: "Tuple",
13487e2e9c0cSopenharmony_ci            },
13497e2e9c0cSopenharmony_ci            Token::StructEnd,
13507e2e9c0cSopenharmony_ci        ],
13517e2e9c0cSopenharmony_ci    );
13527e2e9c0cSopenharmony_ci
13537e2e9c0cSopenharmony_ci    // struct with tag first
13547e2e9c0cSopenharmony_ci    assert_tokens(
13557e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Struct::<u8> { f: 1 },
13567e2e9c0cSopenharmony_ci        &[
13577e2e9c0cSopenharmony_ci            Token::Struct {
13587e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13597e2e9c0cSopenharmony_ci                len: 2,
13607e2e9c0cSopenharmony_ci            },
13617e2e9c0cSopenharmony_ci            Token::Str("t"),
13627e2e9c0cSopenharmony_ci            Token::UnitVariant {
13637e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13647e2e9c0cSopenharmony_ci                variant: "Struct",
13657e2e9c0cSopenharmony_ci            },
13667e2e9c0cSopenharmony_ci            Token::Str("c"),
13677e2e9c0cSopenharmony_ci            Token::Struct {
13687e2e9c0cSopenharmony_ci                name: "Struct",
13697e2e9c0cSopenharmony_ci                len: 1,
13707e2e9c0cSopenharmony_ci            },
13717e2e9c0cSopenharmony_ci            Token::Str("f"),
13727e2e9c0cSopenharmony_ci            Token::U8(1),
13737e2e9c0cSopenharmony_ci            Token::StructEnd,
13747e2e9c0cSopenharmony_ci            Token::StructEnd,
13757e2e9c0cSopenharmony_ci        ],
13767e2e9c0cSopenharmony_ci    );
13777e2e9c0cSopenharmony_ci
13787e2e9c0cSopenharmony_ci    // struct with content first
13797e2e9c0cSopenharmony_ci    assert_de_tokens(
13807e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Struct::<u8> { f: 1 },
13817e2e9c0cSopenharmony_ci        &[
13827e2e9c0cSopenharmony_ci            Token::Struct {
13837e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13847e2e9c0cSopenharmony_ci                len: 2,
13857e2e9c0cSopenharmony_ci            },
13867e2e9c0cSopenharmony_ci            Token::Str("c"),
13877e2e9c0cSopenharmony_ci            Token::Struct {
13887e2e9c0cSopenharmony_ci                name: "Struct",
13897e2e9c0cSopenharmony_ci                len: 1,
13907e2e9c0cSopenharmony_ci            },
13917e2e9c0cSopenharmony_ci            Token::Str("f"),
13927e2e9c0cSopenharmony_ci            Token::U8(1),
13937e2e9c0cSopenharmony_ci            Token::StructEnd,
13947e2e9c0cSopenharmony_ci            Token::Str("t"),
13957e2e9c0cSopenharmony_ci            Token::UnitVariant {
13967e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
13977e2e9c0cSopenharmony_ci                variant: "Struct",
13987e2e9c0cSopenharmony_ci            },
13997e2e9c0cSopenharmony_ci            Token::StructEnd,
14007e2e9c0cSopenharmony_ci        ],
14017e2e9c0cSopenharmony_ci    );
14027e2e9c0cSopenharmony_ci
14037e2e9c0cSopenharmony_ci    // integer field keys
14047e2e9c0cSopenharmony_ci    assert_de_tokens(
14057e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Newtype::<u8>(1),
14067e2e9c0cSopenharmony_ci        &[
14077e2e9c0cSopenharmony_ci            Token::Struct {
14087e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14097e2e9c0cSopenharmony_ci                len: 2,
14107e2e9c0cSopenharmony_ci            },
14117e2e9c0cSopenharmony_ci            Token::U64(1), // content field
14127e2e9c0cSopenharmony_ci            Token::U8(1),
14137e2e9c0cSopenharmony_ci            Token::U64(0), // tag field
14147e2e9c0cSopenharmony_ci            Token::UnitVariant {
14157e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14167e2e9c0cSopenharmony_ci                variant: "Newtype",
14177e2e9c0cSopenharmony_ci            },
14187e2e9c0cSopenharmony_ci            Token::StructEnd,
14197e2e9c0cSopenharmony_ci        ],
14207e2e9c0cSopenharmony_ci    );
14217e2e9c0cSopenharmony_ci
14227e2e9c0cSopenharmony_ci    // byte-array field keys
14237e2e9c0cSopenharmony_ci    assert_de_tokens(
14247e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Newtype::<u8>(1),
14257e2e9c0cSopenharmony_ci        &[
14267e2e9c0cSopenharmony_ci            Token::Struct {
14277e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14287e2e9c0cSopenharmony_ci                len: 2,
14297e2e9c0cSopenharmony_ci            },
14307e2e9c0cSopenharmony_ci            Token::Bytes(b"c"),
14317e2e9c0cSopenharmony_ci            Token::U8(1),
14327e2e9c0cSopenharmony_ci            Token::Bytes(b"t"),
14337e2e9c0cSopenharmony_ci            Token::UnitVariant {
14347e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14357e2e9c0cSopenharmony_ci                variant: "Newtype",
14367e2e9c0cSopenharmony_ci            },
14377e2e9c0cSopenharmony_ci            Token::StructEnd,
14387e2e9c0cSopenharmony_ci        ],
14397e2e9c0cSopenharmony_ci    );
14407e2e9c0cSopenharmony_ci}
14417e2e9c0cSopenharmony_ci
14427e2e9c0cSopenharmony_ci#[test]
14437e2e9c0cSopenharmony_cifn test_adjacently_tagged_enum_deny_unknown_fields() {
14447e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
14457e2e9c0cSopenharmony_ci    #[serde(tag = "t", content = "c", deny_unknown_fields)]
14467e2e9c0cSopenharmony_ci    enum AdjacentlyTagged {
14477e2e9c0cSopenharmony_ci        Unit,
14487e2e9c0cSopenharmony_ci    }
14497e2e9c0cSopenharmony_ci
14507e2e9c0cSopenharmony_ci    assert_de_tokens(
14517e2e9c0cSopenharmony_ci        &AdjacentlyTagged::Unit,
14527e2e9c0cSopenharmony_ci        &[
14537e2e9c0cSopenharmony_ci            Token::Struct {
14547e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14557e2e9c0cSopenharmony_ci                len: 2,
14567e2e9c0cSopenharmony_ci            },
14577e2e9c0cSopenharmony_ci            Token::Str("t"),
14587e2e9c0cSopenharmony_ci            Token::UnitVariant {
14597e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14607e2e9c0cSopenharmony_ci                variant: "Unit",
14617e2e9c0cSopenharmony_ci            },
14627e2e9c0cSopenharmony_ci            Token::Str("c"),
14637e2e9c0cSopenharmony_ci            Token::Unit,
14647e2e9c0cSopenharmony_ci            Token::StructEnd,
14657e2e9c0cSopenharmony_ci        ],
14667e2e9c0cSopenharmony_ci    );
14677e2e9c0cSopenharmony_ci
14687e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AdjacentlyTagged>(
14697e2e9c0cSopenharmony_ci        &[
14707e2e9c0cSopenharmony_ci            Token::Struct {
14717e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14727e2e9c0cSopenharmony_ci                len: 2,
14737e2e9c0cSopenharmony_ci            },
14747e2e9c0cSopenharmony_ci            Token::Str("t"),
14757e2e9c0cSopenharmony_ci            Token::UnitVariant {
14767e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14777e2e9c0cSopenharmony_ci                variant: "Unit",
14787e2e9c0cSopenharmony_ci            },
14797e2e9c0cSopenharmony_ci            Token::Str("c"),
14807e2e9c0cSopenharmony_ci            Token::Unit,
14817e2e9c0cSopenharmony_ci            Token::Str("h"),
14827e2e9c0cSopenharmony_ci        ],
14837e2e9c0cSopenharmony_ci        r#"invalid value: string "h", expected "t" or "c""#,
14847e2e9c0cSopenharmony_ci    );
14857e2e9c0cSopenharmony_ci
14867e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AdjacentlyTagged>(
14877e2e9c0cSopenharmony_ci        &[
14887e2e9c0cSopenharmony_ci            Token::Struct {
14897e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
14907e2e9c0cSopenharmony_ci                len: 2,
14917e2e9c0cSopenharmony_ci            },
14927e2e9c0cSopenharmony_ci            Token::Str("h"),
14937e2e9c0cSopenharmony_ci        ],
14947e2e9c0cSopenharmony_ci        r#"invalid value: string "h", expected "t" or "c""#,
14957e2e9c0cSopenharmony_ci    );
14967e2e9c0cSopenharmony_ci
14977e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AdjacentlyTagged>(
14987e2e9c0cSopenharmony_ci        &[
14997e2e9c0cSopenharmony_ci            Token::Struct {
15007e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
15017e2e9c0cSopenharmony_ci                len: 2,
15027e2e9c0cSopenharmony_ci            },
15037e2e9c0cSopenharmony_ci            Token::Str("c"),
15047e2e9c0cSopenharmony_ci            Token::Unit,
15057e2e9c0cSopenharmony_ci            Token::Str("h"),
15067e2e9c0cSopenharmony_ci        ],
15077e2e9c0cSopenharmony_ci        r#"invalid value: string "h", expected "t" or "c""#,
15087e2e9c0cSopenharmony_ci    );
15097e2e9c0cSopenharmony_ci
15107e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AdjacentlyTagged>(
15117e2e9c0cSopenharmony_ci        &[
15127e2e9c0cSopenharmony_ci            Token::Struct {
15137e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
15147e2e9c0cSopenharmony_ci                len: 2,
15157e2e9c0cSopenharmony_ci            },
15167e2e9c0cSopenharmony_ci            Token::U64(0), // tag field
15177e2e9c0cSopenharmony_ci            Token::UnitVariant {
15187e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
15197e2e9c0cSopenharmony_ci                variant: "Unit",
15207e2e9c0cSopenharmony_ci            },
15217e2e9c0cSopenharmony_ci            Token::U64(3),
15227e2e9c0cSopenharmony_ci        ],
15237e2e9c0cSopenharmony_ci        r#"invalid value: integer `3`, expected "t" or "c""#,
15247e2e9c0cSopenharmony_ci    );
15257e2e9c0cSopenharmony_ci
15267e2e9c0cSopenharmony_ci    assert_de_tokens_error::<AdjacentlyTagged>(
15277e2e9c0cSopenharmony_ci        &[
15287e2e9c0cSopenharmony_ci            Token::Struct {
15297e2e9c0cSopenharmony_ci                name: "AdjacentlyTagged",
15307e2e9c0cSopenharmony_ci                len: 2,
15317e2e9c0cSopenharmony_ci            },
15327e2e9c0cSopenharmony_ci            Token::Bytes(b"c"),
15337e2e9c0cSopenharmony_ci            Token::Unit,
15347e2e9c0cSopenharmony_ci            Token::Bytes(b"h"),
15357e2e9c0cSopenharmony_ci        ],
15367e2e9c0cSopenharmony_ci        r#"invalid value: byte array, expected "t" or "c""#,
15377e2e9c0cSopenharmony_ci    );
15387e2e9c0cSopenharmony_ci}
15397e2e9c0cSopenharmony_ci
15407e2e9c0cSopenharmony_ci#[test]
15417e2e9c0cSopenharmony_cifn test_enum_in_internally_tagged_enum() {
15427e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
15437e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
15447e2e9c0cSopenharmony_ci    enum Outer {
15457e2e9c0cSopenharmony_ci        Inner(Inner),
15467e2e9c0cSopenharmony_ci    }
15477e2e9c0cSopenharmony_ci
15487e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
15497e2e9c0cSopenharmony_ci    enum Inner {
15507e2e9c0cSopenharmony_ci        Unit,
15517e2e9c0cSopenharmony_ci        Newtype(u8),
15527e2e9c0cSopenharmony_ci        Tuple(u8, u8),
15537e2e9c0cSopenharmony_ci        Struct { f: u8 },
15547e2e9c0cSopenharmony_ci    }
15557e2e9c0cSopenharmony_ci
15567e2e9c0cSopenharmony_ci    assert_tokens(
15577e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Unit),
15587e2e9c0cSopenharmony_ci        &[
15597e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
15607e2e9c0cSopenharmony_ci            Token::Str("type"),
15617e2e9c0cSopenharmony_ci            Token::Str("Inner"),
15627e2e9c0cSopenharmony_ci            Token::Str("Unit"),
15637e2e9c0cSopenharmony_ci            Token::Unit,
15647e2e9c0cSopenharmony_ci            Token::MapEnd,
15657e2e9c0cSopenharmony_ci        ],
15667e2e9c0cSopenharmony_ci    );
15677e2e9c0cSopenharmony_ci
15687e2e9c0cSopenharmony_ci    assert_tokens(
15697e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Newtype(1)),
15707e2e9c0cSopenharmony_ci        &[
15717e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
15727e2e9c0cSopenharmony_ci            Token::Str("type"),
15737e2e9c0cSopenharmony_ci            Token::Str("Inner"),
15747e2e9c0cSopenharmony_ci            Token::Str("Newtype"),
15757e2e9c0cSopenharmony_ci            Token::U8(1),
15767e2e9c0cSopenharmony_ci            Token::MapEnd,
15777e2e9c0cSopenharmony_ci        ],
15787e2e9c0cSopenharmony_ci    );
15797e2e9c0cSopenharmony_ci
15807e2e9c0cSopenharmony_ci    // Reaches crate::private::de::content::VariantDeserializer::tuple_variant
15817e2e9c0cSopenharmony_ci    // Content::Seq case
15827e2e9c0cSopenharmony_ci    // via ContentDeserializer::deserialize_enum
15837e2e9c0cSopenharmony_ci    assert_tokens(
15847e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Tuple(1, 1)),
15857e2e9c0cSopenharmony_ci        &[
15867e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
15877e2e9c0cSopenharmony_ci            Token::Str("type"),
15887e2e9c0cSopenharmony_ci            Token::Str("Inner"),
15897e2e9c0cSopenharmony_ci            Token::Str("Tuple"),
15907e2e9c0cSopenharmony_ci            Token::TupleStruct {
15917e2e9c0cSopenharmony_ci                name: "Tuple",
15927e2e9c0cSopenharmony_ci                len: 2,
15937e2e9c0cSopenharmony_ci            },
15947e2e9c0cSopenharmony_ci            Token::U8(1),
15957e2e9c0cSopenharmony_ci            Token::U8(1),
15967e2e9c0cSopenharmony_ci            Token::TupleStructEnd,
15977e2e9c0cSopenharmony_ci            Token::MapEnd,
15987e2e9c0cSopenharmony_ci        ],
15997e2e9c0cSopenharmony_ci    );
16007e2e9c0cSopenharmony_ci
16017e2e9c0cSopenharmony_ci    // Reaches crate::private::de::content::VariantDeserializer::struct_variant
16027e2e9c0cSopenharmony_ci    // Content::Map case
16037e2e9c0cSopenharmony_ci    // via ContentDeserializer::deserialize_enum
16047e2e9c0cSopenharmony_ci    assert_tokens(
16057e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Struct { f: 1 }),
16067e2e9c0cSopenharmony_ci        &[
16077e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
16087e2e9c0cSopenharmony_ci            Token::Str("type"),
16097e2e9c0cSopenharmony_ci            Token::Str("Inner"),
16107e2e9c0cSopenharmony_ci            Token::Str("Struct"),
16117e2e9c0cSopenharmony_ci            Token::Struct {
16127e2e9c0cSopenharmony_ci                name: "Struct",
16137e2e9c0cSopenharmony_ci                len: 1,
16147e2e9c0cSopenharmony_ci            },
16157e2e9c0cSopenharmony_ci            Token::Str("f"),
16167e2e9c0cSopenharmony_ci            Token::U8(1),
16177e2e9c0cSopenharmony_ci            Token::StructEnd,
16187e2e9c0cSopenharmony_ci            Token::MapEnd,
16197e2e9c0cSopenharmony_ci        ],
16207e2e9c0cSopenharmony_ci    );
16217e2e9c0cSopenharmony_ci
16227e2e9c0cSopenharmony_ci    // Reaches crate::private::de::content::VariantDeserializer::struct_variant
16237e2e9c0cSopenharmony_ci    // Content::Seq case
16247e2e9c0cSopenharmony_ci    // via ContentDeserializer::deserialize_enum
16257e2e9c0cSopenharmony_ci    assert_de_tokens(
16267e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Struct { f: 1 }),
16277e2e9c0cSopenharmony_ci        &[
16287e2e9c0cSopenharmony_ci            Token::Map { len: Some(2) },
16297e2e9c0cSopenharmony_ci            Token::Str("type"),
16307e2e9c0cSopenharmony_ci            Token::Str("Inner"),
16317e2e9c0cSopenharmony_ci            Token::Str("Struct"),
16327e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
16337e2e9c0cSopenharmony_ci            Token::U8(1), // f
16347e2e9c0cSopenharmony_ci            Token::SeqEnd,
16357e2e9c0cSopenharmony_ci            Token::MapEnd,
16367e2e9c0cSopenharmony_ci        ],
16377e2e9c0cSopenharmony_ci    );
16387e2e9c0cSopenharmony_ci}
16397e2e9c0cSopenharmony_ci
16407e2e9c0cSopenharmony_ci#[test]
16417e2e9c0cSopenharmony_cifn test_internally_tagged_struct() {
16427e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16437e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
16447e2e9c0cSopenharmony_ci    pub struct Struct {
16457e2e9c0cSopenharmony_ci        a: u8,
16467e2e9c0cSopenharmony_ci    }
16477e2e9c0cSopenharmony_ci
16487e2e9c0cSopenharmony_ci    assert_tokens(
16497e2e9c0cSopenharmony_ci        &Struct { a: 1 },
16507e2e9c0cSopenharmony_ci        &[
16517e2e9c0cSopenharmony_ci            Token::Struct {
16527e2e9c0cSopenharmony_ci                name: "Struct",
16537e2e9c0cSopenharmony_ci                len: 2,
16547e2e9c0cSopenharmony_ci            },
16557e2e9c0cSopenharmony_ci            Token::Str("type"),
16567e2e9c0cSopenharmony_ci            Token::Str("Struct"),
16577e2e9c0cSopenharmony_ci            Token::Str("a"),
16587e2e9c0cSopenharmony_ci            Token::U8(1),
16597e2e9c0cSopenharmony_ci            Token::StructEnd,
16607e2e9c0cSopenharmony_ci        ],
16617e2e9c0cSopenharmony_ci    );
16627e2e9c0cSopenharmony_ci
16637e2e9c0cSopenharmony_ci    assert_de_tokens(
16647e2e9c0cSopenharmony_ci        &Struct { a: 1 },
16657e2e9c0cSopenharmony_ci        &[
16667e2e9c0cSopenharmony_ci            Token::Struct {
16677e2e9c0cSopenharmony_ci                name: "Struct",
16687e2e9c0cSopenharmony_ci                len: 1,
16697e2e9c0cSopenharmony_ci            },
16707e2e9c0cSopenharmony_ci            Token::Str("a"),
16717e2e9c0cSopenharmony_ci            Token::U8(1),
16727e2e9c0cSopenharmony_ci            Token::StructEnd,
16737e2e9c0cSopenharmony_ci        ],
16747e2e9c0cSopenharmony_ci    );
16757e2e9c0cSopenharmony_ci}
16767e2e9c0cSopenharmony_ci
16777e2e9c0cSopenharmony_ci#[test]
16787e2e9c0cSopenharmony_cifn test_internally_tagged_braced_struct_with_zero_fields() {
16797e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16807e2e9c0cSopenharmony_ci    #[serde(tag = "type")]
16817e2e9c0cSopenharmony_ci    struct S {}
16827e2e9c0cSopenharmony_ci
16837e2e9c0cSopenharmony_ci    assert_tokens(
16847e2e9c0cSopenharmony_ci        &S {},
16857e2e9c0cSopenharmony_ci        &[
16867e2e9c0cSopenharmony_ci            Token::Struct { name: "S", len: 1 },
16877e2e9c0cSopenharmony_ci            Token::Str("type"),
16887e2e9c0cSopenharmony_ci            Token::Str("S"),
16897e2e9c0cSopenharmony_ci            Token::StructEnd,
16907e2e9c0cSopenharmony_ci        ],
16917e2e9c0cSopenharmony_ci    );
16927e2e9c0cSopenharmony_ci}
16937e2e9c0cSopenharmony_ci
16947e2e9c0cSopenharmony_ci#[test]
16957e2e9c0cSopenharmony_cifn test_internally_tagged_struct_with_flattened_field() {
16967e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
16977e2e9c0cSopenharmony_ci    #[serde(tag = "tag_struct")]
16987e2e9c0cSopenharmony_ci    pub struct Struct {
16997e2e9c0cSopenharmony_ci        #[serde(flatten)]
17007e2e9c0cSopenharmony_ci        pub flat: Enum,
17017e2e9c0cSopenharmony_ci    }
17027e2e9c0cSopenharmony_ci
17037e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
17047e2e9c0cSopenharmony_ci    #[serde(tag = "tag_enum", content = "content")]
17057e2e9c0cSopenharmony_ci    pub enum Enum {
17067e2e9c0cSopenharmony_ci        A(u64),
17077e2e9c0cSopenharmony_ci    }
17087e2e9c0cSopenharmony_ci
17097e2e9c0cSopenharmony_ci    assert_tokens(
17107e2e9c0cSopenharmony_ci        &Struct { flat: Enum::A(0) },
17117e2e9c0cSopenharmony_ci        &[
17127e2e9c0cSopenharmony_ci            Token::Map { len: None },
17137e2e9c0cSopenharmony_ci            Token::Str("tag_struct"),
17147e2e9c0cSopenharmony_ci            Token::Str("Struct"),
17157e2e9c0cSopenharmony_ci            Token::Str("tag_enum"),
17167e2e9c0cSopenharmony_ci            Token::UnitVariant {
17177e2e9c0cSopenharmony_ci                name: "Enum",
17187e2e9c0cSopenharmony_ci                variant: "A",
17197e2e9c0cSopenharmony_ci            },
17207e2e9c0cSopenharmony_ci            Token::Str("content"),
17217e2e9c0cSopenharmony_ci            Token::U64(0),
17227e2e9c0cSopenharmony_ci            Token::MapEnd,
17237e2e9c0cSopenharmony_ci        ],
17247e2e9c0cSopenharmony_ci    );
17257e2e9c0cSopenharmony_ci
17267e2e9c0cSopenharmony_ci    assert_de_tokens(
17277e2e9c0cSopenharmony_ci        &Struct { flat: Enum::A(0) },
17287e2e9c0cSopenharmony_ci        &[
17297e2e9c0cSopenharmony_ci            Token::Map { len: None },
17307e2e9c0cSopenharmony_ci            Token::Str("tag_enum"),
17317e2e9c0cSopenharmony_ci            Token::Str("A"),
17327e2e9c0cSopenharmony_ci            Token::Str("content"),
17337e2e9c0cSopenharmony_ci            Token::U64(0),
17347e2e9c0cSopenharmony_ci            Token::MapEnd,
17357e2e9c0cSopenharmony_ci        ],
17367e2e9c0cSopenharmony_ci    );
17377e2e9c0cSopenharmony_ci}
17387e2e9c0cSopenharmony_ci
17397e2e9c0cSopenharmony_ci#[test]
17407e2e9c0cSopenharmony_cifn test_untagged_enum_with_flattened_integer_key() {
17417e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
17427e2e9c0cSopenharmony_ci    #[serde(untagged)]
17437e2e9c0cSopenharmony_ci    pub enum Untagged {
17447e2e9c0cSopenharmony_ci        Variant {
17457e2e9c0cSopenharmony_ci            #[serde(flatten)]
17467e2e9c0cSopenharmony_ci            map: BTreeMap<u64, String>,
17477e2e9c0cSopenharmony_ci        },
17487e2e9c0cSopenharmony_ci    }
17497e2e9c0cSopenharmony_ci
17507e2e9c0cSopenharmony_ci    assert_tokens(
17517e2e9c0cSopenharmony_ci        &Untagged::Variant {
17527e2e9c0cSopenharmony_ci            map: {
17537e2e9c0cSopenharmony_ci                let mut map = BTreeMap::new();
17547e2e9c0cSopenharmony_ci                map.insert(100, "BTreeMap".to_owned());
17557e2e9c0cSopenharmony_ci                map
17567e2e9c0cSopenharmony_ci            },
17577e2e9c0cSopenharmony_ci        },
17587e2e9c0cSopenharmony_ci        &[
17597e2e9c0cSopenharmony_ci            Token::Map { len: None },
17607e2e9c0cSopenharmony_ci            Token::U64(100),
17617e2e9c0cSopenharmony_ci            Token::Str("BTreeMap"),
17627e2e9c0cSopenharmony_ci            Token::MapEnd,
17637e2e9c0cSopenharmony_ci        ],
17647e2e9c0cSopenharmony_ci    );
17657e2e9c0cSopenharmony_ci}
17667e2e9c0cSopenharmony_ci
17677e2e9c0cSopenharmony_ci#[test]
17687e2e9c0cSopenharmony_cifn test_enum_in_untagged_enum() {
17697e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
17707e2e9c0cSopenharmony_ci    #[serde(untagged)]
17717e2e9c0cSopenharmony_ci    enum Outer {
17727e2e9c0cSopenharmony_ci        Inner(Inner),
17737e2e9c0cSopenharmony_ci    }
17747e2e9c0cSopenharmony_ci
17757e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
17767e2e9c0cSopenharmony_ci    enum Inner {
17777e2e9c0cSopenharmony_ci        Unit,
17787e2e9c0cSopenharmony_ci        Newtype(u8),
17797e2e9c0cSopenharmony_ci        Tuple(u8, u8),
17807e2e9c0cSopenharmony_ci        Struct { f: u8 },
17817e2e9c0cSopenharmony_ci    }
17827e2e9c0cSopenharmony_ci
17837e2e9c0cSopenharmony_ci    assert_tokens(
17847e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Unit),
17857e2e9c0cSopenharmony_ci        &[Token::UnitVariant {
17867e2e9c0cSopenharmony_ci            name: "Inner",
17877e2e9c0cSopenharmony_ci            variant: "Unit",
17887e2e9c0cSopenharmony_ci        }],
17897e2e9c0cSopenharmony_ci    );
17907e2e9c0cSopenharmony_ci
17917e2e9c0cSopenharmony_ci    assert_tokens(
17927e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Newtype(1)),
17937e2e9c0cSopenharmony_ci        &[
17947e2e9c0cSopenharmony_ci            Token::NewtypeVariant {
17957e2e9c0cSopenharmony_ci                name: "Inner",
17967e2e9c0cSopenharmony_ci                variant: "Newtype",
17977e2e9c0cSopenharmony_ci            },
17987e2e9c0cSopenharmony_ci            Token::U8(1),
17997e2e9c0cSopenharmony_ci        ],
18007e2e9c0cSopenharmony_ci    );
18017e2e9c0cSopenharmony_ci
18027e2e9c0cSopenharmony_ci    assert_tokens(
18037e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Tuple(1, 1)),
18047e2e9c0cSopenharmony_ci        &[
18057e2e9c0cSopenharmony_ci            Token::TupleVariant {
18067e2e9c0cSopenharmony_ci                name: "Inner",
18077e2e9c0cSopenharmony_ci                variant: "Tuple",
18087e2e9c0cSopenharmony_ci                len: 2,
18097e2e9c0cSopenharmony_ci            },
18107e2e9c0cSopenharmony_ci            Token::U8(1),
18117e2e9c0cSopenharmony_ci            Token::U8(1),
18127e2e9c0cSopenharmony_ci            Token::TupleVariantEnd,
18137e2e9c0cSopenharmony_ci        ],
18147e2e9c0cSopenharmony_ci    );
18157e2e9c0cSopenharmony_ci
18167e2e9c0cSopenharmony_ci    assert_tokens(
18177e2e9c0cSopenharmony_ci        &Outer::Inner(Inner::Struct { f: 1 }),
18187e2e9c0cSopenharmony_ci        &[
18197e2e9c0cSopenharmony_ci            Token::StructVariant {
18207e2e9c0cSopenharmony_ci                name: "Inner",
18217e2e9c0cSopenharmony_ci                variant: "Struct",
18227e2e9c0cSopenharmony_ci                len: 1,
18237e2e9c0cSopenharmony_ci            },
18247e2e9c0cSopenharmony_ci            Token::Str("f"),
18257e2e9c0cSopenharmony_ci            Token::U8(1),
18267e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
18277e2e9c0cSopenharmony_ci        ],
18287e2e9c0cSopenharmony_ci    );
18297e2e9c0cSopenharmony_ci}
18307e2e9c0cSopenharmony_ci
18317e2e9c0cSopenharmony_ci#[test]
18327e2e9c0cSopenharmony_cifn test_untagged_bytes() {
18337e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Deserialize)]
18347e2e9c0cSopenharmony_ci    #[serde(untagged)]
18357e2e9c0cSopenharmony_ci    enum Untagged {
18367e2e9c0cSopenharmony_ci        String {
18377e2e9c0cSopenharmony_ci            string: String,
18387e2e9c0cSopenharmony_ci        },
18397e2e9c0cSopenharmony_ci        Bytes {
18407e2e9c0cSopenharmony_ci            #[serde(with = "bytes")]
18417e2e9c0cSopenharmony_ci            bytes: Vec<u8>,
18427e2e9c0cSopenharmony_ci        },
18437e2e9c0cSopenharmony_ci    }
18447e2e9c0cSopenharmony_ci
18457e2e9c0cSopenharmony_ci    assert_de_tokens(
18467e2e9c0cSopenharmony_ci        &Untagged::String {
18477e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
18487e2e9c0cSopenharmony_ci        },
18497e2e9c0cSopenharmony_ci        &[
18507e2e9c0cSopenharmony_ci            Token::Struct {
18517e2e9c0cSopenharmony_ci                name: "Untagged",
18527e2e9c0cSopenharmony_ci                len: 1,
18537e2e9c0cSopenharmony_ci            },
18547e2e9c0cSopenharmony_ci            Token::Str("string"),
18557e2e9c0cSopenharmony_ci            Token::Str("\0"),
18567e2e9c0cSopenharmony_ci            Token::StructEnd,
18577e2e9c0cSopenharmony_ci        ],
18587e2e9c0cSopenharmony_ci    );
18597e2e9c0cSopenharmony_ci
18607e2e9c0cSopenharmony_ci    assert_de_tokens(
18617e2e9c0cSopenharmony_ci        &Untagged::String {
18627e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
18637e2e9c0cSopenharmony_ci        },
18647e2e9c0cSopenharmony_ci        &[
18657e2e9c0cSopenharmony_ci            Token::Struct {
18667e2e9c0cSopenharmony_ci                name: "Untagged",
18677e2e9c0cSopenharmony_ci                len: 1,
18687e2e9c0cSopenharmony_ci            },
18697e2e9c0cSopenharmony_ci            Token::Str("string"),
18707e2e9c0cSopenharmony_ci            Token::String("\0"),
18717e2e9c0cSopenharmony_ci            Token::StructEnd,
18727e2e9c0cSopenharmony_ci        ],
18737e2e9c0cSopenharmony_ci    );
18747e2e9c0cSopenharmony_ci
18757e2e9c0cSopenharmony_ci    assert_de_tokens(
18767e2e9c0cSopenharmony_ci        &Untagged::String {
18777e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
18787e2e9c0cSopenharmony_ci        },
18797e2e9c0cSopenharmony_ci        &[
18807e2e9c0cSopenharmony_ci            Token::Struct {
18817e2e9c0cSopenharmony_ci                name: "Untagged",
18827e2e9c0cSopenharmony_ci                len: 1,
18837e2e9c0cSopenharmony_ci            },
18847e2e9c0cSopenharmony_ci            Token::Str("string"),
18857e2e9c0cSopenharmony_ci            Token::Bytes(b"\0"),
18867e2e9c0cSopenharmony_ci            Token::StructEnd,
18877e2e9c0cSopenharmony_ci        ],
18887e2e9c0cSopenharmony_ci    );
18897e2e9c0cSopenharmony_ci
18907e2e9c0cSopenharmony_ci    assert_de_tokens(
18917e2e9c0cSopenharmony_ci        &Untagged::String {
18927e2e9c0cSopenharmony_ci            string: "\0".to_owned(),
18937e2e9c0cSopenharmony_ci        },
18947e2e9c0cSopenharmony_ci        &[
18957e2e9c0cSopenharmony_ci            Token::Struct {
18967e2e9c0cSopenharmony_ci                name: "Untagged",
18977e2e9c0cSopenharmony_ci                len: 1,
18987e2e9c0cSopenharmony_ci            },
18997e2e9c0cSopenharmony_ci            Token::Str("string"),
19007e2e9c0cSopenharmony_ci            Token::ByteBuf(b"\0"),
19017e2e9c0cSopenharmony_ci            Token::StructEnd,
19027e2e9c0cSopenharmony_ci        ],
19037e2e9c0cSopenharmony_ci    );
19047e2e9c0cSopenharmony_ci
19057e2e9c0cSopenharmony_ci    assert_de_tokens(
19067e2e9c0cSopenharmony_ci        &Untagged::Bytes { bytes: vec![0] },
19077e2e9c0cSopenharmony_ci        &[
19087e2e9c0cSopenharmony_ci            Token::Struct {
19097e2e9c0cSopenharmony_ci                name: "Untagged",
19107e2e9c0cSopenharmony_ci                len: 1,
19117e2e9c0cSopenharmony_ci            },
19127e2e9c0cSopenharmony_ci            Token::Str("bytes"),
19137e2e9c0cSopenharmony_ci            Token::Str("\0"),
19147e2e9c0cSopenharmony_ci            Token::StructEnd,
19157e2e9c0cSopenharmony_ci        ],
19167e2e9c0cSopenharmony_ci    );
19177e2e9c0cSopenharmony_ci
19187e2e9c0cSopenharmony_ci    assert_de_tokens(
19197e2e9c0cSopenharmony_ci        &Untagged::Bytes { bytes: vec![0] },
19207e2e9c0cSopenharmony_ci        &[
19217e2e9c0cSopenharmony_ci            Token::Struct {
19227e2e9c0cSopenharmony_ci                name: "Untagged",
19237e2e9c0cSopenharmony_ci                len: 1,
19247e2e9c0cSopenharmony_ci            },
19257e2e9c0cSopenharmony_ci            Token::Str("bytes"),
19267e2e9c0cSopenharmony_ci            Token::String("\0"),
19277e2e9c0cSopenharmony_ci            Token::StructEnd,
19287e2e9c0cSopenharmony_ci        ],
19297e2e9c0cSopenharmony_ci    );
19307e2e9c0cSopenharmony_ci
19317e2e9c0cSopenharmony_ci    assert_de_tokens(
19327e2e9c0cSopenharmony_ci        &Untagged::Bytes { bytes: vec![0] },
19337e2e9c0cSopenharmony_ci        &[
19347e2e9c0cSopenharmony_ci            Token::Struct {
19357e2e9c0cSopenharmony_ci                name: "Untagged",
19367e2e9c0cSopenharmony_ci                len: 1,
19377e2e9c0cSopenharmony_ci            },
19387e2e9c0cSopenharmony_ci            Token::Str("bytes"),
19397e2e9c0cSopenharmony_ci            Token::Bytes(b"\0"),
19407e2e9c0cSopenharmony_ci            Token::StructEnd,
19417e2e9c0cSopenharmony_ci        ],
19427e2e9c0cSopenharmony_ci    );
19437e2e9c0cSopenharmony_ci
19447e2e9c0cSopenharmony_ci    assert_de_tokens(
19457e2e9c0cSopenharmony_ci        &Untagged::Bytes { bytes: vec![0] },
19467e2e9c0cSopenharmony_ci        &[
19477e2e9c0cSopenharmony_ci            Token::Struct {
19487e2e9c0cSopenharmony_ci                name: "Untagged",
19497e2e9c0cSopenharmony_ci                len: 1,
19507e2e9c0cSopenharmony_ci            },
19517e2e9c0cSopenharmony_ci            Token::Str("bytes"),
19527e2e9c0cSopenharmony_ci            Token::ByteBuf(b"\0"),
19537e2e9c0cSopenharmony_ci            Token::StructEnd,
19547e2e9c0cSopenharmony_ci        ],
19557e2e9c0cSopenharmony_ci    );
19567e2e9c0cSopenharmony_ci
19577e2e9c0cSopenharmony_ci    assert_de_tokens(
19587e2e9c0cSopenharmony_ci        &Untagged::Bytes { bytes: vec![0] },
19597e2e9c0cSopenharmony_ci        &[
19607e2e9c0cSopenharmony_ci            Token::Struct {
19617e2e9c0cSopenharmony_ci                name: "Untagged",
19627e2e9c0cSopenharmony_ci                len: 1,
19637e2e9c0cSopenharmony_ci            },
19647e2e9c0cSopenharmony_ci            Token::Str("bytes"),
19657e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
19667e2e9c0cSopenharmony_ci            Token::U8(0),
19677e2e9c0cSopenharmony_ci            Token::SeqEnd,
19687e2e9c0cSopenharmony_ci            Token::StructEnd,
19697e2e9c0cSopenharmony_ci        ],
19707e2e9c0cSopenharmony_ci    );
19717e2e9c0cSopenharmony_ci}
19727e2e9c0cSopenharmony_ci
19737e2e9c0cSopenharmony_ci#[test]
19747e2e9c0cSopenharmony_cifn test_rename_all() {
19757e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, Debug, PartialEq)]
19767e2e9c0cSopenharmony_ci    #[serde(rename_all = "snake_case")]
19777e2e9c0cSopenharmony_ci    enum E {
19787e2e9c0cSopenharmony_ci        #[serde(rename_all = "camelCase")]
19797e2e9c0cSopenharmony_ci        Serialize {
19807e2e9c0cSopenharmony_ci            serialize: bool,
19817e2e9c0cSopenharmony_ci            serialize_seq: bool,
19827e2e9c0cSopenharmony_ci        },
19837e2e9c0cSopenharmony_ci        #[serde(rename_all = "kebab-case")]
19847e2e9c0cSopenharmony_ci        SerializeSeq {
19857e2e9c0cSopenharmony_ci            serialize: bool,
19867e2e9c0cSopenharmony_ci            serialize_seq: bool,
19877e2e9c0cSopenharmony_ci        },
19887e2e9c0cSopenharmony_ci        #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
19897e2e9c0cSopenharmony_ci        SerializeMap {
19907e2e9c0cSopenharmony_ci            serialize: bool,
19917e2e9c0cSopenharmony_ci            serialize_seq: bool,
19927e2e9c0cSopenharmony_ci        },
19937e2e9c0cSopenharmony_ci    }
19947e2e9c0cSopenharmony_ci
19957e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, Debug, PartialEq)]
19967e2e9c0cSopenharmony_ci    #[serde(rename_all = "PascalCase")]
19977e2e9c0cSopenharmony_ci    struct S {
19987e2e9c0cSopenharmony_ci        serialize: bool,
19997e2e9c0cSopenharmony_ci        serialize_seq: bool,
20007e2e9c0cSopenharmony_ci    }
20017e2e9c0cSopenharmony_ci
20027e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, Debug, PartialEq)]
20037e2e9c0cSopenharmony_ci    #[serde(rename_all = "SCREAMING-KEBAB-CASE")]
20047e2e9c0cSopenharmony_ci    struct ScreamingKebab {
20057e2e9c0cSopenharmony_ci        serialize: bool,
20067e2e9c0cSopenharmony_ci        serialize_seq: bool,
20077e2e9c0cSopenharmony_ci    }
20087e2e9c0cSopenharmony_ci
20097e2e9c0cSopenharmony_ci    assert_tokens(
20107e2e9c0cSopenharmony_ci        &E::Serialize {
20117e2e9c0cSopenharmony_ci            serialize: true,
20127e2e9c0cSopenharmony_ci            serialize_seq: true,
20137e2e9c0cSopenharmony_ci        },
20147e2e9c0cSopenharmony_ci        &[
20157e2e9c0cSopenharmony_ci            Token::StructVariant {
20167e2e9c0cSopenharmony_ci                name: "E",
20177e2e9c0cSopenharmony_ci                variant: "serialize",
20187e2e9c0cSopenharmony_ci                len: 2,
20197e2e9c0cSopenharmony_ci            },
20207e2e9c0cSopenharmony_ci            Token::Str("serialize"),
20217e2e9c0cSopenharmony_ci            Token::Bool(true),
20227e2e9c0cSopenharmony_ci            Token::Str("serializeSeq"),
20237e2e9c0cSopenharmony_ci            Token::Bool(true),
20247e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
20257e2e9c0cSopenharmony_ci        ],
20267e2e9c0cSopenharmony_ci    );
20277e2e9c0cSopenharmony_ci
20287e2e9c0cSopenharmony_ci    assert_tokens(
20297e2e9c0cSopenharmony_ci        &E::SerializeSeq {
20307e2e9c0cSopenharmony_ci            serialize: true,
20317e2e9c0cSopenharmony_ci            serialize_seq: true,
20327e2e9c0cSopenharmony_ci        },
20337e2e9c0cSopenharmony_ci        &[
20347e2e9c0cSopenharmony_ci            Token::StructVariant {
20357e2e9c0cSopenharmony_ci                name: "E",
20367e2e9c0cSopenharmony_ci                variant: "serialize_seq",
20377e2e9c0cSopenharmony_ci                len: 2,
20387e2e9c0cSopenharmony_ci            },
20397e2e9c0cSopenharmony_ci            Token::Str("serialize"),
20407e2e9c0cSopenharmony_ci            Token::Bool(true),
20417e2e9c0cSopenharmony_ci            Token::Str("serialize-seq"),
20427e2e9c0cSopenharmony_ci            Token::Bool(true),
20437e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
20447e2e9c0cSopenharmony_ci        ],
20457e2e9c0cSopenharmony_ci    );
20467e2e9c0cSopenharmony_ci
20477e2e9c0cSopenharmony_ci    assert_tokens(
20487e2e9c0cSopenharmony_ci        &E::SerializeMap {
20497e2e9c0cSopenharmony_ci            serialize: true,
20507e2e9c0cSopenharmony_ci            serialize_seq: true,
20517e2e9c0cSopenharmony_ci        },
20527e2e9c0cSopenharmony_ci        &[
20537e2e9c0cSopenharmony_ci            Token::StructVariant {
20547e2e9c0cSopenharmony_ci                name: "E",
20557e2e9c0cSopenharmony_ci                variant: "serialize_map",
20567e2e9c0cSopenharmony_ci                len: 2,
20577e2e9c0cSopenharmony_ci            },
20587e2e9c0cSopenharmony_ci            Token::Str("SERIALIZE"),
20597e2e9c0cSopenharmony_ci            Token::Bool(true),
20607e2e9c0cSopenharmony_ci            Token::Str("SERIALIZE_SEQ"),
20617e2e9c0cSopenharmony_ci            Token::Bool(true),
20627e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
20637e2e9c0cSopenharmony_ci        ],
20647e2e9c0cSopenharmony_ci    );
20657e2e9c0cSopenharmony_ci
20667e2e9c0cSopenharmony_ci    assert_tokens(
20677e2e9c0cSopenharmony_ci        &S {
20687e2e9c0cSopenharmony_ci            serialize: true,
20697e2e9c0cSopenharmony_ci            serialize_seq: true,
20707e2e9c0cSopenharmony_ci        },
20717e2e9c0cSopenharmony_ci        &[
20727e2e9c0cSopenharmony_ci            Token::Struct { name: "S", len: 2 },
20737e2e9c0cSopenharmony_ci            Token::Str("Serialize"),
20747e2e9c0cSopenharmony_ci            Token::Bool(true),
20757e2e9c0cSopenharmony_ci            Token::Str("SerializeSeq"),
20767e2e9c0cSopenharmony_ci            Token::Bool(true),
20777e2e9c0cSopenharmony_ci            Token::StructEnd,
20787e2e9c0cSopenharmony_ci        ],
20797e2e9c0cSopenharmony_ci    );
20807e2e9c0cSopenharmony_ci
20817e2e9c0cSopenharmony_ci    assert_tokens(
20827e2e9c0cSopenharmony_ci        &ScreamingKebab {
20837e2e9c0cSopenharmony_ci            serialize: true,
20847e2e9c0cSopenharmony_ci            serialize_seq: true,
20857e2e9c0cSopenharmony_ci        },
20867e2e9c0cSopenharmony_ci        &[
20877e2e9c0cSopenharmony_ci            Token::Struct {
20887e2e9c0cSopenharmony_ci                name: "ScreamingKebab",
20897e2e9c0cSopenharmony_ci                len: 2,
20907e2e9c0cSopenharmony_ci            },
20917e2e9c0cSopenharmony_ci            Token::Str("SERIALIZE"),
20927e2e9c0cSopenharmony_ci            Token::Bool(true),
20937e2e9c0cSopenharmony_ci            Token::Str("SERIALIZE-SEQ"),
20947e2e9c0cSopenharmony_ci            Token::Bool(true),
20957e2e9c0cSopenharmony_ci            Token::StructEnd,
20967e2e9c0cSopenharmony_ci        ],
20977e2e9c0cSopenharmony_ci    );
20987e2e9c0cSopenharmony_ci}
20997e2e9c0cSopenharmony_ci
21007e2e9c0cSopenharmony_ci#[test]
21017e2e9c0cSopenharmony_cifn test_rename_all_fields() {
21027e2e9c0cSopenharmony_ci    #[derive(Serialize, Deserialize, Debug, PartialEq)]
21037e2e9c0cSopenharmony_ci    #[serde(rename_all_fields = "kebab-case")]
21047e2e9c0cSopenharmony_ci    enum E {
21057e2e9c0cSopenharmony_ci        V1,
21067e2e9c0cSopenharmony_ci        V2(bool),
21077e2e9c0cSopenharmony_ci        V3 {
21087e2e9c0cSopenharmony_ci            a_field: bool,
21097e2e9c0cSopenharmony_ci            another_field: bool,
21107e2e9c0cSopenharmony_ci            #[serde(rename = "last-field")]
21117e2e9c0cSopenharmony_ci            yet_another_field: bool,
21127e2e9c0cSopenharmony_ci        },
21137e2e9c0cSopenharmony_ci        #[serde(rename_all = "snake_case")]
21147e2e9c0cSopenharmony_ci        V4 {
21157e2e9c0cSopenharmony_ci            a_field: bool,
21167e2e9c0cSopenharmony_ci        },
21177e2e9c0cSopenharmony_ci    }
21187e2e9c0cSopenharmony_ci
21197e2e9c0cSopenharmony_ci    assert_tokens(
21207e2e9c0cSopenharmony_ci        &E::V3 {
21217e2e9c0cSopenharmony_ci            a_field: true,
21227e2e9c0cSopenharmony_ci            another_field: true,
21237e2e9c0cSopenharmony_ci            yet_another_field: true,
21247e2e9c0cSopenharmony_ci        },
21257e2e9c0cSopenharmony_ci        &[
21267e2e9c0cSopenharmony_ci            Token::StructVariant {
21277e2e9c0cSopenharmony_ci                name: "E",
21287e2e9c0cSopenharmony_ci                variant: "V3",
21297e2e9c0cSopenharmony_ci                len: 3,
21307e2e9c0cSopenharmony_ci            },
21317e2e9c0cSopenharmony_ci            Token::Str("a-field"),
21327e2e9c0cSopenharmony_ci            Token::Bool(true),
21337e2e9c0cSopenharmony_ci            Token::Str("another-field"),
21347e2e9c0cSopenharmony_ci            Token::Bool(true),
21357e2e9c0cSopenharmony_ci            Token::Str("last-field"),
21367e2e9c0cSopenharmony_ci            Token::Bool(true),
21377e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
21387e2e9c0cSopenharmony_ci        ],
21397e2e9c0cSopenharmony_ci    );
21407e2e9c0cSopenharmony_ci
21417e2e9c0cSopenharmony_ci    assert_tokens(
21427e2e9c0cSopenharmony_ci        &E::V4 { a_field: true },
21437e2e9c0cSopenharmony_ci        &[
21447e2e9c0cSopenharmony_ci            Token::StructVariant {
21457e2e9c0cSopenharmony_ci                name: "E",
21467e2e9c0cSopenharmony_ci                variant: "V4",
21477e2e9c0cSopenharmony_ci                len: 1,
21487e2e9c0cSopenharmony_ci            },
21497e2e9c0cSopenharmony_ci            Token::Str("a_field"),
21507e2e9c0cSopenharmony_ci            Token::Bool(true),
21517e2e9c0cSopenharmony_ci            Token::StructVariantEnd,
21527e2e9c0cSopenharmony_ci        ],
21537e2e9c0cSopenharmony_ci    );
21547e2e9c0cSopenharmony_ci}
21557e2e9c0cSopenharmony_ci
21567e2e9c0cSopenharmony_ci#[test]
21577e2e9c0cSopenharmony_cifn test_untagged_newtype_variant_containing_unit_struct_not_map() {
21587e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
21597e2e9c0cSopenharmony_ci    struct Unit;
21607e2e9c0cSopenharmony_ci
21617e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
21627e2e9c0cSopenharmony_ci    #[serde(untagged)]
21637e2e9c0cSopenharmony_ci    enum Message {
21647e2e9c0cSopenharmony_ci        Unit(Unit),
21657e2e9c0cSopenharmony_ci        Map(BTreeMap<String, String>),
21667e2e9c0cSopenharmony_ci    }
21677e2e9c0cSopenharmony_ci
21687e2e9c0cSopenharmony_ci    assert_tokens(
21697e2e9c0cSopenharmony_ci        &Message::Map(BTreeMap::new()),
21707e2e9c0cSopenharmony_ci        &[Token::Map { len: Some(0) }, Token::MapEnd],
21717e2e9c0cSopenharmony_ci    );
21727e2e9c0cSopenharmony_ci}
21737e2e9c0cSopenharmony_ci
21747e2e9c0cSopenharmony_ci#[test]
21757e2e9c0cSopenharmony_cifn test_internally_tagged_newtype_variant_containing_unit_struct() {
21767e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
21777e2e9c0cSopenharmony_ci    struct Info;
21787e2e9c0cSopenharmony_ci
21797e2e9c0cSopenharmony_ci    #[derive(Debug, PartialEq, Serialize, Deserialize)]
21807e2e9c0cSopenharmony_ci    #[serde(tag = "topic")]
21817e2e9c0cSopenharmony_ci    enum Message {
21827e2e9c0cSopenharmony_ci        Info(Info),
21837e2e9c0cSopenharmony_ci    }
21847e2e9c0cSopenharmony_ci
21857e2e9c0cSopenharmony_ci    assert_tokens(
21867e2e9c0cSopenharmony_ci        &Message::Info(Info),
21877e2e9c0cSopenharmony_ci        &[
21887e2e9c0cSopenharmony_ci            Token::Map { len: Some(1) },
21897e2e9c0cSopenharmony_ci            Token::Str("topic"),
21907e2e9c0cSopenharmony_ci            Token::Str("Info"),
21917e2e9c0cSopenharmony_ci            Token::MapEnd,
21927e2e9c0cSopenharmony_ci        ],
21937e2e9c0cSopenharmony_ci    );
21947e2e9c0cSopenharmony_ci
21957e2e9c0cSopenharmony_ci    assert_de_tokens(
21967e2e9c0cSopenharmony_ci        &Message::Info(Info),
21977e2e9c0cSopenharmony_ci        &[
21987e2e9c0cSopenharmony_ci            Token::Struct {
21997e2e9c0cSopenharmony_ci                name: "Message",
22007e2e9c0cSopenharmony_ci                len: 1,
22017e2e9c0cSopenharmony_ci            },
22027e2e9c0cSopenharmony_ci            Token::Str("topic"),
22037e2e9c0cSopenharmony_ci            Token::Str("Info"),
22047e2e9c0cSopenharmony_ci            Token::StructEnd,
22057e2e9c0cSopenharmony_ci        ],
22067e2e9c0cSopenharmony_ci    );
22077e2e9c0cSopenharmony_ci
22087e2e9c0cSopenharmony_ci    assert_de_tokens(
22097e2e9c0cSopenharmony_ci        &Message::Info(Info),
22107e2e9c0cSopenharmony_ci        &[
22117e2e9c0cSopenharmony_ci            Token::Seq { len: Some(1) },
22127e2e9c0cSopenharmony_ci            Token::Str("Info"),
22137e2e9c0cSopenharmony_ci            Token::SeqEnd,
22147e2e9c0cSopenharmony_ci        ],
22157e2e9c0cSopenharmony_ci    );
22167e2e9c0cSopenharmony_ci}
22177e2e9c0cSopenharmony_ci
22187e2e9c0cSopenharmony_ci#[test]
22197e2e9c0cSopenharmony_cifn test_packed_struct_can_derive_serialize() {
22207e2e9c0cSopenharmony_ci    #[derive(Copy, Clone, Serialize)]
22217e2e9c0cSopenharmony_ci    #[repr(packed, C)]
22227e2e9c0cSopenharmony_ci    struct PackedC {
22237e2e9c0cSopenharmony_ci        t: f32,
22247e2e9c0cSopenharmony_ci    }
22257e2e9c0cSopenharmony_ci
22267e2e9c0cSopenharmony_ci    #[derive(Copy, Clone, Serialize)]
22277e2e9c0cSopenharmony_ci    #[repr(C, packed)]
22287e2e9c0cSopenharmony_ci    struct CPacked {
22297e2e9c0cSopenharmony_ci        t: f32,
22307e2e9c0cSopenharmony_ci    }
22317e2e9c0cSopenharmony_ci
22327e2e9c0cSopenharmony_ci    #[derive(Copy, Clone, Serialize)]
22337e2e9c0cSopenharmony_ci    #[repr(C, packed(2))]
22347e2e9c0cSopenharmony_ci    struct CPacked2 {
22357e2e9c0cSopenharmony_ci        t: f32,
22367e2e9c0cSopenharmony_ci    }
22377e2e9c0cSopenharmony_ci
22387e2e9c0cSopenharmony_ci    #[derive(Copy, Clone, Serialize)]
22397e2e9c0cSopenharmony_ci    #[repr(packed(2), C)]
22407e2e9c0cSopenharmony_ci    struct Packed2C {
22417e2e9c0cSopenharmony_ci        t: f32,
22427e2e9c0cSopenharmony_ci    }
22437e2e9c0cSopenharmony_ci}
2244