// Copyright 2017 Serde Developer // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // 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. #![deny(warnings)] #![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::option::Option as StdOption; 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; #[allow(dead_code)] struct Option; #[allow(dead_code)] struct Some; #[allow(dead_code)] struct None; ////////////////////////////////////////////////////////////////////////// #[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: StdOption<&'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: StdOption, boxed: Box, option_boxed: StdOption>, } 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: StdOption<&'a str>, b: StdOption<&'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; #[derive(Serialize, Deserialize)] struct EmptyArray { empty: [X; 0], } enum Or { A(A), B(B), } #[derive(Serialize, Deserialize)] #[serde(untagged, remote = "Or")] enum OrDef { #[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, #[serde(borrow, with = "StrDef")] s: Str<'a>, } #[derive(Serialize, Deserialize)] enum BorrowVariant<'a> { #[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::(); #[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::(); #[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::(); #[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::(); #[derive(Serialize, Deserialize)] struct StaticStrStruct<'a> { a: &'a str, b: &'static str, } #[derive(Serialize, Deserialize)] struct StaticStrTupleStruct<'a>(&'a str, &'static str); #[derive(Serialize, Deserialize)] struct StaticStrNewtypeStruct(&'static str); #[derive(Serialize, Deserialize)] enum StaticStrEnum<'a> { Struct { a: &'a str, b: &'static str, }, Tuple(&'a str, &'static str), Newtype(&'static str), } #[derive(Serialize, Deserialize)] struct SkippedStaticStr { #[serde(skip_deserializing)] skipped: &'static str, other: isize, } assert::(); macro_rules! T { () => { () } } #[derive(Serialize, Deserialize)] struct TypeMacro { mac: T!(), marker: PhantomData, } assert::>(); } ////////////////////////////////////////////////////////////////////////// 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!() } } pub fn serialize_some_unit_variant(_: S) -> StdResult 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(_: &str, _: &u8, _: S) -> StdResult 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 }