// These just test that serde_codegen is able to produce code that compiles // successfully when there are a variety of generics and non-(de)serializable // types involved. #![cfg_attr(feature = "unstable", feature(non_ascii_idents))] #[macro_use] extern crate serde_derive; extern crate serde; use self::serde::ser::{Serialize, Serializer}; use self::serde::de::{DeserializeOwned, Deserializer}; use std::borrow::Cow; use std::marker::PhantomData; 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; #[allow(dead_code)] struct Ok; #[allow(dead_code)] struct Err; ////////////////////////////////////////////////////////////////////////// #[test] fn test_gen() { #[derive(Serialize, Deserialize)] struct With { t: T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] x: X, } assert::>(); #[derive(Serialize, Deserialize)] struct WithTogether { t: T, #[serde(with="both_x")] x: X, } assert::>(); #[derive(Serialize, Deserialize)] struct WithRef<'a, T: 'a> { #[serde(skip_deserializing)] t: Option<&'a T>, #[serde(serialize_with="ser_x", deserialize_with="de_x")] x: X, } assert::>(); #[derive(Serialize, Deserialize)] struct PhantomX { x: PhantomData, } assert::(); #[derive(Serialize, Deserialize)] struct PhantomT { t: PhantomData, } assert::>(); #[derive(Serialize, Deserialize)] struct NoBounds { t: T, option: Option, boxed: Box, option_boxed: Option>, } assert::>(); #[derive(Serialize, Deserialize)] enum EnumWith { Unit, Newtype( #[serde(serialize_with="ser_x", deserialize_with="de_x")] X), Tuple( T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] X), Struct { t: T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] x: X }, } assert::>(); #[derive(Serialize)] struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a { t: T, rrrt: &'a &'b &'c T, } assert_ser::>(); #[derive(Serialize, Deserialize)] struct Newtype( #[serde(serialize_with="ser_x", deserialize_with="de_x")] X ); assert::(); #[derive(Serialize, Deserialize)] struct Tuple( T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] X, ); assert::>(); #[derive(Serialize, Deserialize)] enum TreeNode { Split { left: Box>, right: Box>, }, Leaf { data: D, }, } assert::>(); #[derive(Serialize, Deserialize)] struct ListNode { data: D, next: Box>, } assert::>(); #[derive(Serialize, Deserialize)] struct RecursiveA { b: Box, } assert::(); #[derive(Serialize, Deserialize)] enum RecursiveB { A(RecursiveA), } assert::(); #[derive(Serialize, Deserialize)] struct RecursiveGenericA { t: T, b: Box>, } assert::>(); #[derive(Serialize, Deserialize)] enum RecursiveGenericB { T(T), A(RecursiveGenericA), } assert::>(); #[derive(Serialize)] struct OptionStatic<'a> { a: Option<&'a str>, b: Option<&'static str>, } assert_ser::(); #[derive(Serialize, Deserialize)] #[serde(bound="D: SerializeWith + DeserializeWith")] struct WithTraits1 { #[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::>(); #[derive(Serialize, Deserialize)] #[serde(bound(serialize="D: SerializeWith", deserialize="D: DeserializeWith"))] struct WithTraits2 { #[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::>(); #[derive(Serialize, Deserialize)] struct CowStr<'a>(Cow<'a, str>); assert::(); #[derive(Serialize, Deserialize)] #[serde(bound(deserialize = "T::Owned: DeserializeOwned"))] struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>); assert::>(); #[derive(Serialize, Deserialize)] struct EmptyStruct {} assert::(); #[derive(Serialize, Deserialize)] enum EmptyEnumVariant { EmptyStruct {}, } assert::(); #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] struct NonAsciiIdents { σ: f64 } #[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, } #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] struct EmptyTuple(); #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] struct EmptyTupleDenyUnknown(); #[derive(Serialize, Deserialize)] struct TupleSkipAll(#[serde(skip_deserializing)] u8); #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8); #[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, } #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] enum EmptyVariants { Braced {}, Tuple(), BracedSkip { #[serde(skip_deserializing)] f: u8, }, TupleSkip(#[serde(skip_deserializing)] u8), } #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] enum EmptyVariantsDenyUnknown { Braced {}, Tuple(), BracedSkip { #[serde(skip_deserializing)] f: u8, }, TupleSkip(#[serde(skip_deserializing)] u8), } #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] struct UnitDenyUnknown; } ////////////////////////////////////////////////////////////////////////// fn assert() {} fn assert_ser() {} trait SerializeWith { fn serialize_with(_: &Self, _: S) -> StdResult; } trait DeserializeWith: Sized { fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult; } // Implements neither Serialize nor Deserialize pub struct X; pub fn ser_x(_: &X, _: S) -> StdResult { unimplemented!() } pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult { unimplemented!() } mod both_x { pub use super::{ser_x as serialize, de_x as deserialize}; } impl SerializeWith for X { fn serialize_with(_: &Self, _: S) -> StdResult { unimplemented!() } } impl DeserializeWith for X { fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult { unimplemented!() } }