serde/test_suite/tests/test_macros.rs

1084 lines
22 KiB
Rust
Raw Normal View History

2017-04-13 19:34:42 -05:00
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
extern crate serde_test;
2017-04-13 14:28:23 -05:00
use self::serde_test::{Error, Token, assert_tokens, assert_ser_tokens, assert_de_tokens,
assert_de_tokens_error};
2017-02-02 14:10:07 -06:00
use std::collections::BTreeMap;
use std::marker::PhantomData;
// That tests that the derived Serialize implementation doesn't trigger
// any warning about `serializer` not being used, in case of empty enums.
#[derive(Serialize)]
#[allow(dead_code)]
#[deny(unused_variables)]
enum Void {}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
2015-03-03 22:29:59 -06:00
struct NamedUnit;
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedTuple<A, B, C>(A, B, C);
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
#[derive(Debug, PartialEq, Serialize)]
2017-04-13 14:28:23 -05:00
enum SerEnum<'a, B: 'a, C: 'a, D>
where
D: 'a,
{
Unit,
2017-04-13 14:28:23 -05:00
Seq(i8, B, &'a C, &'a mut D),
Map { a: i8, b: B, c: &'a C, d: &'a mut D },
// Make sure we can support more than one variant.
_Unit2,
2017-04-13 14:28:23 -05:00
_Seq2(i8, B, &'a C, &'a mut D),
_Map2 { a: i8, b: B, c: &'a C, d: &'a mut D },
}
2015-08-27 22:01:09 -05:00
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum DeEnum<B, C, D> {
Unit,
2017-04-13 14:28:23 -05:00
Seq(i8, B, C, D),
Map { a: i8, b: B, c: C, d: D },
// Make sure we can support more than one variant.
_Unit2,
2017-04-13 14:28:23 -05:00
_Seq2(i8, B, C, D),
_Map2 { a: i8, b: B, c: C, d: D },
}
#[derive(Serialize)]
enum Lifetimes<'a> {
LifetimeSeq(&'a i32),
NoLifetimeSeq(i32),
LifetimeMap { a: &'a i32 },
NoLifetimeMap { a: i32 },
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericStruct<T> {
x: T,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericNewTypeStruct<T>(T);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericTupleStruct<T, U>(T, U);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum GenericEnum<T, U> {
Unit,
NewType(T),
Seq(T, U),
Map { x: T, y: U },
}
trait AssociatedType {
type X;
}
impl AssociatedType for i32 {
type X = i32;
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
2017-04-13 14:28:23 -05:00
struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
phantom: PhantomData<T>,
}
#[test]
fn test_named_unit() {
2017-04-13 14:28:23 -05:00
assert_tokens(&NamedUnit, &[Token::UnitStruct("NamedUnit")]);
}
#[test]
fn test_ser_named_tuple() {
let a = 5;
let mut b = 6;
let c = 7;
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&SerNamedTuple(&a, &mut b, c),
&[
2017-04-05 12:40:14 -05:00
Token::TupleStruct("SerNamedTuple", 3),
2015-08-27 22:01:09 -05:00
Token::I32(5),
Token::I32(6),
Token::I32(7),
Token::TupleStructEnd,
2015-08-27 22:01:09 -05:00
],
);
}
#[test]
fn test_de_named_tuple() {
2015-08-27 22:01:09 -05:00
assert_de_tokens(
&DeNamedTuple(5, 6, 7),
&[
2017-04-05 12:40:14 -05:00
Token::Seq(Some(3)),
2015-08-27 22:01:09 -05:00
Token::I32(5),
Token::I32(6),
Token::I32(7),
Token::SeqEnd,
2017-04-13 14:28:23 -05:00
],
);
assert_de_tokens(
&DeNamedTuple(5, 6, 7),
&[
2017-04-05 12:40:14 -05:00
Token::TupleStruct("DeNamedTuple", 3),
Token::I32(5),
Token::I32(6),
Token::I32(7),
Token::TupleStructEnd,
2017-04-13 14:28:23 -05:00
],
);
}
#[test]
fn test_ser_named_map() {
let a = 5;
let mut b = 6;
let c = 7;
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&SerNamedMap {
2017-04-13 14:28:23 -05:00
a: &a,
b: &mut b,
c: c,
},
2015-08-27 22:01:09 -05:00
&[
2017-04-05 12:40:14 -05:00
Token::Struct("SerNamedMap", 3),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I32(5),
Token::Str("b"),
Token::I32(6),
Token::Str("c"),
Token::I32(7),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
}
#[test]
fn test_de_named_map() {
2015-08-27 22:01:09 -05:00
assert_de_tokens(
2017-04-13 14:28:23 -05:00
&DeNamedMap { a: 5, b: 6, c: 7 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("DeNamedMap", 3),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I32(5),
Token::Str("b"),
Token::I32(6),
Token::Str("c"),
Token::I32(7),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_ser_enum_unit() {
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&SerEnum::Unit::<u32, u32, u32>,
2017-04-13 14:28:23 -05:00
&[Token::UnitVariant("SerEnum", "Unit")],
);
}
#[test]
fn test_ser_enum_seq() {
let a = 1;
let b = 2;
let c = 3;
let mut d = 4;
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
2017-04-13 14:28:23 -05:00
&SerEnum::Seq(a, b, &c, &mut d),
2015-08-27 22:01:09 -05:00
&[
2017-04-05 12:40:14 -05:00
Token::TupleVariant("SerEnum", "Seq", 4),
2015-08-27 22:01:09 -05:00
Token::I8(1),
Token::I32(2),
Token::I32(3),
Token::I32(4),
2017-04-05 12:40:14 -05:00
Token::TupleVariantEnd,
2015-08-27 22:01:09 -05:00
],
);
}
#[test]
fn test_ser_enum_map() {
let a = 1;
let b = 2;
let c = 3;
let mut d = 4;
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&SerEnum::Map {
2017-04-13 14:28:23 -05:00
a: a,
b: b,
c: &c,
d: &mut d,
},
2015-08-27 22:01:09 -05:00
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("SerEnum", "Map", 4),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I8(1),
Token::Str("b"),
Token::I32(2),
Token::Str("c"),
Token::I32(3),
Token::Str("d"),
Token::I32(4),
2015-08-27 22:01:09 -05:00
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2015-08-27 22:01:09 -05:00
],
);
}
#[test]
fn test_de_enum_unit() {
2015-08-27 22:01:09 -05:00
assert_tokens(
&DeEnum::Unit::<u32, u32, u32>,
2017-04-13 14:28:23 -05:00
&[Token::UnitVariant("DeEnum", "Unit")],
);
}
#[test]
fn test_de_enum_seq() {
let a = 1;
let b = 2;
let c = 3;
let d = 4;
2015-08-27 22:01:09 -05:00
assert_tokens(
2017-04-13 14:28:23 -05:00
&DeEnum::Seq(a, b, c, d),
&[
2017-04-05 12:40:14 -05:00
Token::TupleVariant("DeEnum", "Seq", 4),
2015-08-27 22:01:09 -05:00
Token::I8(1),
Token::I32(2),
Token::I32(3),
Token::I32(4),
2017-04-05 12:40:14 -05:00
Token::TupleVariantEnd,
2015-08-27 22:01:09 -05:00
],
);
}
#[test]
fn test_de_enum_map() {
let a = 1;
let b = 2;
let c = 3;
let d = 4;
2015-08-27 22:01:09 -05:00
assert_tokens(
&DeEnum::Map {
2017-04-13 14:28:23 -05:00
a: a,
b: b,
c: c,
d: d,
},
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("DeEnum", "Map", 4),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I8(1),
Token::Str("b"),
Token::I32(2),
Token::Str("c"),
Token::I32(3),
Token::Str("d"),
Token::I32(4),
2015-08-27 22:01:09 -05:00
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2015-08-27 22:01:09 -05:00
],
);
}
#[test]
fn test_lifetimes() {
let value = 5;
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&Lifetimes::LifetimeSeq(&value),
&[
2017-04-05 12:40:14 -05:00
Token::NewtypeVariant("Lifetimes", "LifetimeSeq"),
2015-08-27 22:01:09 -05:00
Token::I32(5),
2017-04-13 14:28:23 -05:00
],
);
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&Lifetimes::NoLifetimeSeq(5),
&[
2017-04-05 12:40:14 -05:00
Token::NewtypeVariant("Lifetimes", "NoLifetimeSeq"),
2015-08-27 22:01:09 -05:00
Token::I32(5),
2017-04-13 14:28:23 -05:00
],
);
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&Lifetimes::LifetimeMap { a: &value },
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("Lifetimes", "LifetimeMap", 1),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I32(5),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
);
2015-08-27 22:01:09 -05:00
assert_ser_tokens(
&Lifetimes::NoLifetimeMap { a: 5 },
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("Lifetimes", "NoLifetimeMap", 1),
2015-08-27 22:01:09 -05:00
Token::Str("a"),
Token::I32(5),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
);
}
2015-08-27 22:01:09 -05:00
#[test]
fn test_generic_struct() {
assert_tokens(
&GenericStruct { x: 5u32 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("GenericStruct", 1),
2015-08-27 22:01:09 -05:00
Token::Str("x"),
Token::U32(5),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
2015-08-27 22:01:09 -05:00
#[test]
fn test_generic_newtype_struct() {
assert_tokens(
&GenericNewTypeStruct(5u32),
2017-04-13 14:28:23 -05:00
&[Token::NewtypeStruct("GenericNewTypeStruct"), Token::U32(5)],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_generic_tuple_struct() {
assert_tokens(
&GenericTupleStruct(5u32, 6u32),
&[
2017-04-05 12:40:14 -05:00
Token::TupleStruct("GenericTupleStruct", 2),
2015-08-27 22:01:09 -05:00
Token::U32(5),
Token::U32(6),
Token::TupleStructEnd,
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_generic_enum_unit() {
assert_tokens(
&GenericEnum::Unit::<u32, u32>,
2017-04-13 14:28:23 -05:00
&[Token::UnitVariant("GenericEnum", "Unit")],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_generic_enum_newtype() {
assert_tokens(
&GenericEnum::NewType::<u32, u32>(5),
&[
2017-04-05 12:40:14 -05:00
Token::NewtypeVariant("GenericEnum", "NewType"),
2015-08-27 22:01:09 -05:00
Token::U32(5),
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_generic_enum_seq() {
assert_tokens(
&GenericEnum::Seq::<u32, u32>(5, 6),
&[
2017-04-05 12:40:14 -05:00
Token::TupleVariant("GenericEnum", "Seq", 2),
2015-08-27 22:01:09 -05:00
Token::U32(5),
Token::U32(6),
2017-04-05 12:40:14 -05:00
Token::TupleVariantEnd,
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_generic_enum_map() {
assert_tokens(
&GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("GenericEnum", "Map", 2),
2015-08-27 22:01:09 -05:00
Token::Str("x"),
Token::U32(5),
Token::Str("y"),
Token::U32(6),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
2015-08-27 22:01:09 -05:00
);
}
#[test]
fn test_default_ty_param() {
assert_tokens(
&DefaultTyParam::<i32> { phantom: PhantomData },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("DefaultTyParam", 1),
Token::Str("phantom"),
Token::UnitStruct("PhantomData"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
}
#[test]
fn test_enum_state_field() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum SomeEnum {
Key { key: char, state: bool },
}
assert_tokens(
2017-04-13 14:28:23 -05:00
&SomeEnum::Key {
key: 'a',
state: true,
},
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("SomeEnum", "Key", 2),
Token::Str("key"),
Token::Char('a'),
Token::Str("state"),
Token::Bool(true),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
);
}
2017-02-02 14:10:07 -06:00
#[test]
fn test_untagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
enum Untagged {
2017-04-13 14:28:23 -05:00
A { a: u8 },
B { b: u8 },
2017-02-02 14:10:07 -06:00
C,
D(u8),
E(String),
F(u8, u8),
}
assert_tokens(
&Untagged::A { a: 1 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("Untagged", 1),
2017-02-02 14:10:07 -06:00
Token::Str("a"),
Token::U8(1),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&Untagged::B { b: 2 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("Untagged", 1),
2017-02-02 14:10:07 -06:00
Token::Str("b"),
Token::U8(2),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
2017-04-13 14:28:23 -05:00
assert_tokens(&Untagged::C, &[Token::Unit]);
2017-02-02 14:10:07 -06:00
2017-04-13 14:28:23 -05:00
assert_tokens(&Untagged::D(4), &[Token::U8(4)]);
assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]);
2017-02-02 14:10:07 -06:00
assert_tokens(
&Untagged::F(1, 2),
2017-04-13 14:28:23 -05:00
&[Token::Tuple(2), Token::U8(1), Token::U8(2), Token::TupleEnd],
2017-02-02 14:10:07 -06:00
);
assert_de_tokens_error::<Untagged>(
2017-04-13 14:28:23 -05:00
&[Token::None],
Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),),
2017-02-02 14:10:07 -06:00
);
assert_de_tokens_error::<Untagged>(
2017-04-13 14:28:23 -05:00
&[Token::Tuple(1), Token::U8(1), Token::TupleEnd],
Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),),
2017-02-02 14:10:07 -06:00
);
2017-02-03 00:12:07 -06:00
assert_de_tokens_error::<Untagged>(
&[
2017-04-05 12:40:14 -05:00
Token::Tuple(3),
2017-02-03 00:12:07 -06:00
Token::U8(1),
Token::U8(2),
Token::U8(3),
Token::TupleEnd,
],
2017-04-13 14:28:23 -05:00
Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),),
2017-02-03 00:12:07 -06:00
);
2017-02-02 14:10:07 -06:00
}
#[test]
fn test_internally_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Newtype(BTreeMap<String, String>);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Struct {
f: u8,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
enum InternallyTagged {
2017-04-13 14:28:23 -05:00
A { a: u8 },
B { b: u8 },
2017-02-02 14:10:07 -06:00
C,
D(BTreeMap<String, String>),
E(Newtype),
F(Struct),
}
assert_tokens(
&InternallyTagged::A { a: 1 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("InternallyTagged", 2),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("A"),
Token::Str("a"),
Token::U8(1),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&InternallyTagged::B { b: 2 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("InternallyTagged", 2),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("B"),
Token::Str("b"),
Token::U8(2),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&InternallyTagged::C,
&[
2017-04-05 12:40:14 -05:00
Token::Struct("InternallyTagged", 1),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("C"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&InternallyTagged::D(BTreeMap::new()),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(1)),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("D"),
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&InternallyTagged::E(Newtype(BTreeMap::new())),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(1)),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("E"),
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_tokens(
&InternallyTagged::F(Struct { f: 6 }),
&[
2017-04-05 12:40:14 -05:00
Token::Struct("Struct", 2),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("F"),
Token::Str("f"),
Token::U8(6),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-02 14:10:07 -06:00
);
assert_de_tokens_error::<InternallyTagged>(
2017-04-13 14:28:23 -05:00
&[Token::Map(Some(0)), Token::MapEnd],
2017-02-02 14:10:07 -06:00
Error::Message("missing field `type`".to_owned()),
);
assert_de_tokens_error::<InternallyTagged>(
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(1)),
2017-02-02 14:10:07 -06:00
Token::Str("type"),
Token::Str("Z"),
Token::MapEnd,
],
2017-04-13 14:28:23 -05:00
Error::Message("unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`, `F`".to_owned(),),
2017-02-02 14:10:07 -06:00
);
}
#[test]
fn test_adjacently_tagged_enum() {
2017-02-19 18:04:50 -06:00
#[derive(Debug, PartialEq, Serialize, Deserialize)]
2017-02-19 18:04:39 -06:00
#[serde(tag = "t", content = "c")]
2017-02-19 18:04:50 -06:00
enum AdjacentlyTagged<T> {
2017-02-19 18:04:39 -06:00
Unit,
2017-02-19 18:04:50 -06:00
Newtype(T),
2017-02-19 18:04:39 -06:00
Tuple(u8, u8),
Struct { f: u8 },
}
2017-02-19 18:04:50 -06:00
// unit with no content
assert_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 1),
2017-02-19 18:04:39 -06:00
Token::Str("t"),
Token::Str("Unit"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
2017-02-19 18:04:50 -06:00
// unit with tag first
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 1),
2017-02-19 18:04:50 -06:00
Token::Str("t"),
Token::Str("Unit"),
Token::Str("c"),
Token::Unit,
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-19 18:04:50 -06:00
);
// unit with content first
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 1),
2017-02-19 18:04:50 -06:00
Token::Str("c"),
Token::Unit,
Token::Str("t"),
Token::Str("Unit"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-19 18:04:50 -06:00
);
// newtype with tag first
assert_tokens(
&AdjacentlyTagged::Newtype::<u8>(1),
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:39 -06:00
Token::Str("t"),
Token::Str("Newtype"),
2017-02-19 18:04:39 -06:00
Token::Str("c"),
Token::U8(1),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
2017-02-19 18:04:50 -06:00
// newtype with content first
assert_de_tokens(
&AdjacentlyTagged::Newtype::<u8>(1),
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:50 -06:00
Token::Str("c"),
Token::U8(1),
Token::Str("t"),
Token::Str("Newtype"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-19 18:04:50 -06:00
);
// tuple with tag first
assert_tokens(
&AdjacentlyTagged::Tuple::<u8>(1, 1),
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:39 -06:00
Token::Str("t"),
Token::Str("Tuple"),
2017-02-19 18:04:39 -06:00
Token::Str("c"),
2017-04-05 12:40:14 -05:00
Token::Tuple(2),
2017-02-19 18:04:39 -06:00
Token::U8(1),
Token::U8(1),
Token::TupleEnd,
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
2017-02-19 18:04:50 -06:00
// tuple with content first
assert_de_tokens(
&AdjacentlyTagged::Tuple::<u8>(1, 1),
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:50 -06:00
Token::Str("c"),
2017-04-05 12:40:14 -05:00
Token::Tuple(2),
2017-02-19 18:04:50 -06:00
Token::U8(1),
Token::U8(1),
Token::TupleEnd,
Token::Str("t"),
Token::Str("Tuple"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-19 18:04:50 -06:00
);
// struct with tag first
assert_tokens(
&AdjacentlyTagged::Struct::<u8> { f: 1 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:39 -06:00
Token::Str("t"),
Token::Str("Struct"),
2017-02-19 18:04:39 -06:00
Token::Str("c"),
2017-04-05 12:40:14 -05:00
Token::Struct("Struct", 1),
Token::Str("f"),
2017-02-19 18:04:39 -06:00
Token::U8(1),
Token::StructEnd,
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
);
2017-02-19 18:04:50 -06:00
// struct with content first
assert_de_tokens(
&AdjacentlyTagged::Struct::<u8> { f: 1 },
&[
2017-04-05 12:40:14 -05:00
Token::Struct("AdjacentlyTagged", 2),
2017-02-19 18:04:50 -06:00
Token::Str("c"),
2017-04-05 12:40:14 -05:00
Token::Struct("Struct", 1),
2017-02-19 18:04:50 -06:00
Token::Str("f"),
Token::U8(1),
Token::StructEnd,
Token::Str("t"),
Token::Str("Struct"),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-19 18:04:50 -06:00
);
}
#[test]
fn test_enum_in_internally_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Outer {
Inner(Inner),
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Inner {
Unit,
Newtype(u8),
Tuple(u8, u8),
Struct { f: u8 },
}
assert_tokens(
&Outer::Inner(Inner::Unit),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(2)),
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Unit"),
Token::Unit,
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
);
assert_tokens(
&Outer::Inner(Inner::Newtype(1)),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(2)),
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Newtype"),
Token::U8(1),
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
);
assert_tokens(
&Outer::Inner(Inner::Tuple(1, 1)),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(2)),
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Tuple"),
2017-04-05 12:40:14 -05:00
Token::TupleStruct("Tuple", 2),
Token::U8(1),
Token::U8(1),
Token::TupleStructEnd,
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
);
assert_tokens(
&Outer::Inner(Inner::Struct { f: 1 }),
&[
2017-04-05 12:40:14 -05:00
Token::Map(Some(2)),
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Struct"),
2017-04-05 12:40:14 -05:00
Token::Struct("Struct", 1),
Token::Str("f"),
Token::U8(1),
Token::StructEnd,
Token::MapEnd,
2017-04-13 14:28:23 -05:00
],
);
}
#[test]
fn test_enum_in_untagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
enum Outer {
Inner(Inner),
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Inner {
Unit,
Newtype(u8),
Tuple(u8, u8),
Struct { f: u8 },
}
assert_tokens(
&Outer::Inner(Inner::Unit),
2017-04-13 14:28:23 -05:00
&[Token::UnitVariant("Inner", "Unit")],
);
assert_tokens(
&Outer::Inner(Inner::Newtype(1)),
2017-04-13 14:28:23 -05:00
&[Token::NewtypeVariant("Inner", "Newtype"), Token::U8(1)],
);
assert_tokens(
&Outer::Inner(Inner::Tuple(1, 1)),
&[
2017-04-05 12:40:14 -05:00
Token::TupleVariant("Inner", "Tuple", 2),
Token::U8(1),
Token::U8(1),
2017-04-05 12:40:14 -05:00
Token::TupleVariantEnd,
2017-04-13 14:28:23 -05:00
],
);
assert_tokens(
&Outer::Inner(Inner::Struct { f: 1 }),
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("Inner", "Struct", 1),
Token::Str("f"),
Token::U8(1),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
);
}
2017-02-25 13:58:34 -06:00
#[test]
fn test_rename_all() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case")]
enum E {
#[serde(rename_all = "camelCase")]
Serialize {
serialize: bool,
serialize_seq: bool,
},
#[serde(rename_all = "kebab-case")]
SerializeSeq {
serialize: bool,
serialize_seq: bool,
},
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
SerializeMap {
serialize: bool,
serialize_seq: bool,
},
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "PascalCase")]
struct S {
serialize: bool,
serialize_seq: bool,
}
assert_tokens(
2017-04-13 14:28:23 -05:00
&E::Serialize {
serialize: true,
serialize_seq: true,
},
2017-02-25 13:58:34 -06:00
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("E", "serialize", 2),
2017-02-25 13:58:34 -06:00
Token::Str("serialize"),
Token::Bool(true),
Token::Str("serializeSeq"),
Token::Bool(true),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-25 13:58:34 -06:00
);
assert_tokens(
2017-04-13 14:28:23 -05:00
&E::SerializeSeq {
serialize: true,
serialize_seq: true,
},
2017-02-25 13:58:34 -06:00
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("E", "serialize_seq", 2),
2017-02-25 13:58:34 -06:00
Token::Str("serialize"),
Token::Bool(true),
Token::Str("serialize-seq"),
Token::Bool(true),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-25 13:58:34 -06:00
);
assert_tokens(
2017-04-13 14:28:23 -05:00
&E::SerializeMap {
serialize: true,
serialize_seq: true,
},
2017-02-25 13:58:34 -06:00
&[
2017-04-05 12:40:14 -05:00
Token::StructVariant("E", "serialize_map", 2),
2017-02-25 13:58:34 -06:00
Token::Str("SERIALIZE"),
Token::Bool(true),
Token::Str("SERIALIZE_SEQ"),
Token::Bool(true),
2017-04-05 12:40:14 -05:00
Token::StructVariantEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-25 13:58:34 -06:00
);
assert_tokens(
2017-04-13 14:28:23 -05:00
&S {
serialize: true,
serialize_seq: true,
},
2017-02-25 13:58:34 -06:00
&[
2017-04-05 12:40:14 -05:00
Token::Struct("S", 2),
2017-02-25 13:58:34 -06:00
Token::Str("Serialize"),
Token::Bool(true),
Token::Str("SerializeSeq"),
Token::Bool(true),
Token::StructEnd,
2017-04-13 14:28:23 -05:00
],
2017-02-25 13:58:34 -06:00
);
}