serde/test_suite/tests/test_gen.rs

561 lines
14 KiB
Rust
Raw Normal View History

2017-04-13 19:34:42 -05:00
// Copyright 2017 Serde Developer
//
// 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.
2016-05-07 14:33:59 -05:00
// These just test that serde_codegen is able to produce code that compiles
2016-05-15 17:54:20 -05:00
// successfully when there are a variety of generics and non-(de)serializable
// types involved.
2016-05-07 14:33:59 -05:00
2017-03-08 23:02:15 -06:00
#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
2017-04-07 11:21:30 -05:00
// Clippy false positive
// https://github.com/Manishearth/rust-clippy/issues/292
#![cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
#[macro_use]
extern crate serde_derive;
2016-05-07 14:33:59 -05:00
extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{DeserializeOwned, Deserializer};
2016-05-07 14:33:59 -05:00
use std::borrow::Cow;
use std::marker::PhantomData;
2017-02-01 11:42:12 -06:00
use std::result::Result as StdResult;
// Try to trip up the generated code if it fails to use fully qualified paths.
#[allow(dead_code)]
struct Result;
2017-02-01 11:42:12 -06:00
#[allow(dead_code)]
struct Ok;
#[allow(dead_code)]
struct Err;
2016-05-07 14:33:59 -05:00
//////////////////////////////////////////////////////////////////////////
#[test]
fn test_gen() {
#[derive(Serialize, Deserialize)]
struct With<T> {
t: T,
2016-05-15 17:54:20 -05:00
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
x: X,
}
assert::<With<i32>>();
#[derive(Serialize, Deserialize)]
struct WithTogether<T> {
t: T,
#[serde(with="both_x")]
x: X,
}
assert::<WithTogether<i32>>();
#[derive(Serialize, Deserialize)]
struct WithRef<'a, T: 'a> {
#[serde(skip_deserializing)]
t: Option<&'a T>,
2016-05-15 17:54:20 -05:00
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
x: X,
}
assert::<WithRef<i32>>();
#[derive(Serialize, Deserialize)]
struct PhantomX {
x: PhantomData<X>,
}
assert::<PhantomX>();
#[derive(Serialize, Deserialize)]
struct PhantomT<T> {
t: PhantomData<T>,
}
assert::<PhantomT<X>>();
#[derive(Serialize, Deserialize)]
struct NoBounds<T> {
t: T,
option: Option<T>,
boxed: Box<T>,
option_boxed: Option<Box<T>>,
}
assert::<NoBounds<i32>>();
#[derive(Serialize, Deserialize)]
enum EnumWith<T> {
Unit,
Newtype(
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
2017-04-13 14:28:23 -05:00
X
),
Tuple(
T,
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
2017-04-13 14:28:23 -05:00
X
),
Struct {
t: T,
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
2017-04-13 14:28:23 -05:00
x: X,
},
}
assert::<EnumWith<i32>>();
#[derive(Serialize)]
2017-04-13 14:28:23 -05:00
struct MultipleRef<'a, 'b, 'c, T>
where
T: 'c,
'c: 'b,
'b: 'a,
{
t: T,
rrrt: &'a &'b &'c T,
}
assert_ser::<MultipleRef<i32>>();
2016-05-07 14:33:59 -05:00
#[derive(Serialize, Deserialize)]
struct Newtype(
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
X
);
assert::<Newtype>();
2016-05-19 01:46:06 -05:00
#[derive(Serialize, Deserialize)]
struct Tuple<T>(
T,
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
2017-04-13 14:28:23 -05:00
X
);
assert::<Tuple<i32>>();
#[derive(Serialize, Deserialize)]
enum TreeNode<D> {
Split {
left: Box<TreeNode<D>>,
right: Box<TreeNode<D>>,
},
2017-04-13 14:28:23 -05:00
Leaf { data: D },
}
assert::<TreeNode<i32>>();
#[derive(Serialize, Deserialize)]
struct ListNode<D> {
data: D,
next: Box<ListNode<D>>,
}
assert::<ListNode<i32>>();
#[derive(Serialize, Deserialize)]
struct RecursiveA {
b: Box<RecursiveB>,
}
assert::<RecursiveA>();
#[derive(Serialize, Deserialize)]
enum RecursiveB {
A(RecursiveA),
}
assert::<RecursiveB>();
#[derive(Serialize, Deserialize)]
struct RecursiveGenericA<T> {
t: T,
b: Box<RecursiveGenericB<T>>,
}
assert::<RecursiveGenericA<i32>>();
#[derive(Serialize, Deserialize)]
enum RecursiveGenericB<T> {
T(T),
A(RecursiveGenericA<T>),
}
assert::<RecursiveGenericB<i32>>();
#[derive(Serialize)]
struct OptionStatic<'a> {
a: Option<&'a str>,
b: Option<&'static str>,
}
assert_ser::<OptionStatic>();
#[derive(Serialize, Deserialize)]
#[serde(bound="D: SerializeWith + DeserializeWith")]
struct WithTraits1<D, E> {
#[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with")]
d: D,
#[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with",
bound="E: SerializeWith + DeserializeWith")]
e: E,
}
assert::<WithTraits1<X, X>>();
#[derive(Serialize, Deserialize)]
#[serde(bound(serialize="D: SerializeWith",
deserialize="D: DeserializeWith"))]
struct WithTraits2<D, E> {
#[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with")]
d: D,
#[serde(serialize_with="SerializeWith::serialize_with",
bound(serialize="E: SerializeWith"))]
#[serde(deserialize_with="DeserializeWith::deserialize_with",
bound(deserialize="E: DeserializeWith"))]
e: E,
}
assert::<WithTraits2<X, X>>();
#[derive(Serialize, Deserialize)]
struct CowStr<'a>(Cow<'a, str>);
assert::<CowStr>();
#[derive(Serialize, Deserialize)]
#[serde(bound(deserialize = "T::Owned: DeserializeOwned"))]
struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>);
assert::<CowT<str>>();
#[derive(Serialize, Deserialize)]
struct EmptyStruct {}
assert::<EmptyStruct>();
#[derive(Serialize, Deserialize)]
enum EmptyEnumVariant {
EmptyStruct {},
}
assert::<EmptyEnumVariant>();
2017-01-10 03:20:01 -06:00
2017-03-08 23:02:15 -06:00
#[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)]
2017-01-10 03:20:01 -06:00
struct NonAsciiIdents {
2017-04-13 14:28:23 -05:00
σ: f64,
2017-01-10 03:20:01 -06:00
}
2017-01-11 13:02:24 -06:00
#[derive(Serialize, Deserialize)]
struct EmptyBraced {}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct EmptyBracedDenyUnknown {}
#[derive(Serialize, Deserialize)]
struct BracedSkipAll {
#[serde(skip_deserializing)]
f: u8,
}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct BracedSkipAllDenyUnknown {
#[serde(skip_deserializing)]
f: u8,
}
2017-03-08 23:02:15 -06:00
#[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)]
2017-01-11 13:02:24 -06:00
struct EmptyTuple();
2017-03-08 23:02:15 -06:00
#[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)]
2017-01-11 13:02:24 -06:00
#[serde(deny_unknown_fields)]
struct EmptyTupleDenyUnknown();
#[derive(Serialize, Deserialize)]
2017-04-13 14:28:23 -05:00
struct TupleSkipAll(
#[serde(skip_deserializing)]
u8
);
2017-01-11 13:02:24 -06:00
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
2017-04-13 14:28:23 -05:00
struct TupleSkipAllDenyUnknown(
#[serde(skip_deserializing)]
u8
);
2017-01-11 13:02:24 -06:00
#[derive(Serialize, Deserialize)]
enum EmptyEnum {}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
enum EmptyEnumDenyUnknown {}
#[derive(Serialize, Deserialize)]
enum EnumSkipAll {
#[serde(skip_deserializing)]
#[allow(dead_code)]
Variant,
}
2017-03-08 23:02:15 -06:00
#[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)]
2017-01-11 13:02:24 -06:00
enum EmptyVariants {
Braced {},
Tuple(),
BracedSkip {
#[serde(skip_deserializing)]
f: u8,
},
2017-04-13 14:28:23 -05:00
TupleSkip(
#[serde(skip_deserializing)]
u8
),
2017-01-11 13:02:24 -06:00
}
2017-03-08 23:02:15 -06:00
#[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)]
2017-01-11 13:02:24 -06:00
#[serde(deny_unknown_fields)]
enum EmptyVariantsDenyUnknown {
Braced {},
Tuple(),
BracedSkip {
#[serde(skip_deserializing)]
f: u8,
},
2017-04-13 14:28:23 -05:00
TupleSkip(
#[serde(skip_deserializing)]
u8
),
2017-01-11 13:02:24 -06:00
}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct UnitDenyUnknown;
2017-04-05 19:34:13 -05:00
#[derive(Serialize, Deserialize)]
struct EmptyArray {
empty: [X; 0],
}
enum Or<A, B> {
A(A),
B(B),
}
#[derive(Serialize, Deserialize)]
#[serde(untagged, remote = "Or")]
enum OrDef<A, B> {
#[allow(dead_code)]
A(A),
#[allow(dead_code)]
B(B),
}
struct Str<'a>(&'a str);
#[derive(Serialize, Deserialize)]
#[serde(remote = "Str")]
struct StrDef<'a>(&'a str);
#[derive(Serialize, Deserialize)]
struct Remote<'a> {
#[serde(with = "OrDef")]
or: Or<u8, bool>,
#[serde(borrow, with = "StrDef")]
s: Str<'a>,
}
mod vis {
pub struct S;
#[derive(Serialize, Deserialize)]
#[serde(remote = "S")]
pub struct SDef;
}
// This would not work if SDef::serialize / deserialize are private.
#[derive(Serialize, Deserialize)]
struct RemoteVisibility {
#[serde(with = "vis::SDef")]
s: vis::S,
}
#[derive(Serialize, Deserialize)]
enum ExternallyTaggedVariantWith {
#[allow(dead_code)]
Normal { f1: String },
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
#[allow(dead_code)]
Newtype(X),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Tuple(String, u8),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Struct {
f1: String,
f2: u8,
},
#[serde(serialize_with = "serialize_some_unit_variant")]
#[serde(deserialize_with = "deserialize_some_unit_variant")]
#[allow(dead_code)]
Unit,
}
assert_ser::<ExternallyTaggedVariantWith>();
#[derive(Serialize, Deserialize)]
#[serde(tag = "t")]
enum InternallyTaggedVariantWith {
#[allow(dead_code)]
Normal { f1: String },
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
#[allow(dead_code)]
Newtype(X),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Struct {
f1: String,
f2: u8,
},
#[serde(serialize_with = "serialize_some_unit_variant")]
#[serde(deserialize_with = "deserialize_some_unit_variant")]
#[allow(dead_code)]
Unit,
}
assert_ser::<InternallyTaggedVariantWith>();
#[derive(Serialize, Deserialize)]
#[serde(tag = "t", content = "c")]
enum AdjacentlyTaggedVariantWith {
#[allow(dead_code)]
Normal { f1: String },
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
#[allow(dead_code)]
Newtype(X),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Tuple(String, u8),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Struct {
f1: String,
f2: u8,
},
#[serde(serialize_with = "serialize_some_unit_variant")]
#[serde(deserialize_with = "deserialize_some_unit_variant")]
#[allow(dead_code)]
Unit,
}
assert_ser::<AdjacentlyTaggedVariantWith>();
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum UntaggedVariantWith {
#[allow(dead_code)]
Normal { f1: String },
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
#[allow(dead_code)]
Newtype(X),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Tuple(String, u8),
#[serde(serialize_with = "serialize_some_other_variant")]
#[serde(deserialize_with = "deserialize_some_other_variant")]
#[allow(dead_code)]
Struct {
f1: String,
f2: u8,
},
#[serde(serialize_with = "serialize_some_unit_variant")]
#[serde(deserialize_with = "deserialize_some_unit_variant")]
#[allow(dead_code)]
Unit,
}
assert_ser::<UntaggedVariantWith>();
}
//////////////////////////////////////////////////////////////////////////
fn assert<T: Serialize + DeserializeOwned>() {}
fn assert_ser<T: Serialize>() {}
trait SerializeWith {
2017-01-14 18:07:43 -06:00
fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error>;
}
trait DeserializeWith: Sized {
fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error>;
}
// Implements neither Serialize nor Deserialize
pub struct X;
pub fn ser_x<S: Serializer>(_: &X, _: S) -> StdResult<S::Ok, S::Error> {
unimplemented!()
}
pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult<X, D::Error> {
unimplemented!()
}
mod both_x {
pub use super::{ser_x as serialize, de_x as deserialize};
}
impl SerializeWith for X {
2017-01-14 18:07:43 -06:00
fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error> {
unimplemented!()
}
}
impl DeserializeWith for X {
fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult<Self, D::Error> {
unimplemented!()
}
}
pub fn serialize_some_unit_variant<S>(_: S) -> StdResult<S::Ok, S::Error>
where S: Serializer,
{
unimplemented!()
}
pub fn deserialize_some_unit_variant<'de, D>(_: D) -> StdResult<(), D::Error>
where D: Deserializer<'de>,
{
unimplemented!()
}
pub fn serialize_some_other_variant<S>(_: &str, _: &u8, _: S) -> StdResult<S::Ok, S::Error>
where S: Serializer,
{
unimplemented!()
}
pub fn deserialize_some_other_variant<'de, D>(_: D) -> StdResult<(String, u8), D::Error>
where D: Deserializer<'de>,
{
unimplemented!()
}
pub fn is_zero(n: &u8) -> bool { *n == 0 }