Test items from serde_codegen test suite
diff --git a/tests/all.rs b/tests/all.rs
new file mode 100644
index 0000000..50d70ee
--- /dev/null
+++ b/tests/all.rs
@@ -0,0 +1,597 @@
+extern crate item;
+
+#[macro_use]
+extern crate quote;
+
+/// These are all of the items from serde_codegen's test suite.
+/// Obnoxious whitespace has been added in an attempt to fool the parser.
+#[test]
+fn test_all() {
+ for s in ITEMS {
+ let ast = item::parse(s);
+ let tokens = quote!(#ast).to_string();
+ assert_eq!(ast, item::parse(&tokens));
+ }
+
+ static ITEMS: &'static [&'static str] = &[
+ r#"
+ # [ derive ( Serialize ) ]
+ #[derive(Deserialize)]
+ struct DefaultStruct <A , B, C, D, E> where C : MyDefault , E: MyDefault {
+ a1 : A,
+ #[serde(default)]
+ a2: B,
+ #[serde(default = "MyDefault::my_default")]
+ a3: C,
+ #[serde(skip_deserializing)]
+ a4: D,
+ #[serde(skip_deserializing, default = "MyDefault::my_default")]
+ a5: E,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum DefaultEnum<A, B, C, D, E> where C: MyDefault, E: MyDefault {
+ Struct {
+ a1: A,
+ #[serde(default)]
+ a2: B,
+ #[serde(default = "MyDefault::my_default")]
+ a3: C,
+ #[serde(skip_deserializing)]
+ a4: D,
+ #[serde(skip_deserializing, default = "MyDefault::my_default")]
+ a5: E,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct NoStdDefault(i8);
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct ContainsNoStdDefault <A : MyDefault> {
+ #[serde(default = "MyDefault::my_default")]
+ a: A,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
+ #[serde(skip_deserializing)]
+ a: A,
+ #[serde(skip_deserializing, default)]
+ b: B,
+ #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
+ c: C,
+ #[serde(skip_deserializing, default = "MyDefault::my_default")]
+ e: E,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(deny_unknown_fields)]
+ #[derive(Deserialize)]
+ struct DenyUnknown {
+ a1: i32,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(rename = "Superhero")]
+ #[derive(Deserialize)]
+ struct RenameStruct {
+ a1: i32,
+ #[serde(rename = "a3")]
+ a2: i32,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
+ #[derive(Deserialize)]
+ struct RenameStructSerializeDeserialize {
+ a1: i32,
+ #[serde(rename(serialize = "a4", deserialize = "a5"))]
+ a2: i32,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(rename = "Superhero")]
+ #[derive(Deserialize)]
+ enum RenameEnum {
+
+ #[serde(rename = "bruce_wayne")]
+ Batman ,
+
+ #[serde(rename = "clark_kent")]
+ Superman ( i8 ) ,
+
+ #[serde(rename = "diana_prince")]
+ WonderWoman ( i8 , i8 ) ,
+
+ #[serde(rename = "barry_allan")]
+ Flash {
+ #[serde(rename = "b")]
+ a : i32,
+ } ,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ #[serde ( rename ( serialize = "SuperheroSer" , deserialize = "SuperheroDe" ) ) ]
+ #[derive(Serialize)]
+ enum RenameEnumSerializeDeserialize<A> {
+
+ #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
+ Robin {
+ a: i8,
+ #[serde(rename(serialize = "c"))]
+ #[serde(rename(deserialize = "d"))]
+ b: A,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct SkipSerializingStruct< 'a , B, C> where C : ShouldSkip {
+ a: & 'a i8,
+ #[serde(skip_serializing)]
+ b: B,
+ #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
+ c: C,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip {
+ Struct {
+ a: &'a i8,
+ #[serde(skip_serializing)]
+ _b: B,
+ #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
+ c: C,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct ContainsNotSerialize<'a, B, C, D> where B: 'a , D: SerializeWith {
+ a: &'a Option<i8>,
+ #[serde(skip_serializing)]
+ b: &'a B,
+ #[serde(skip_serializing)]
+ c: Option<C>,
+ #[serde(serialize_with = "SerializeWith::serialize_with")]
+ d: D,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct SerializeWithStruct<'a, B> where B: SerializeWith {
+ a: &'a i8,
+ #[serde(serialize_with = "SerializeWith::serialize_with")]
+ b: B,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ enum SerializeWithEnum<'a, B> where B: SerializeWith {
+ Struct {
+ a: &'a i8,
+ #[serde(serialize_with = "SerializeWith::serialize_with")]
+ b: B,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct DeserializeWithStruct<B> where B: DeserializeWith {
+ a: i8,
+ #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
+ b: B,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ enum DeserializeWithEnum<B> where B: DeserializeWith {
+ Struct {
+ a: i8,
+ #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
+ b: B,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ enum InvalidLengthEnum {
+ A(i32, i32, i32),
+ B(
+ #[serde(skip_deserializing)]
+ i32, i32, i32),
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct TupleStruct(i32, i32, i32);
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct Struct {
+ a: i32,
+ b: i32,
+ #[serde(skip_deserializing)]
+ c: i32,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ enum Enum {
+ Unit,
+ Simple(i32),
+ Seq(i32, i32, i32),
+ Map {
+ a: i32,
+ b: i32,
+ c: i32,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct IgnoreBase {
+ a: i32,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct With<T> {
+ t: T,
+ #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+ x: X,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct WithRef<'a, T: 'a> {
+ #[serde(skip_deserializing)]
+ t: Option<&'a T>,
+ #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+ x: X,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct PhantomX {
+ x: PhantomData<X>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct PhantomT<T> {
+ t: PhantomData<T>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct NoBounds<T> {
+ t: T,
+ option: Option<T>,
+ boxed: Box<T>,
+ option_boxed: Option<Box<T>>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum EnumWith<T> {
+ 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,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
+ t: T,
+ rrrt: &'a &'b &'c T,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct Newtype(
+ #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+ X);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct Tuple<T>(T,
+ #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+ X);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum TreeNode<D> {
+ Split {
+ left: Box<TreeNode<D>>,
+ right: Box<TreeNode<D>>,
+ },
+ Leaf {
+ data: D,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct ListNode<D> {
+ data: D,
+ next: Box<ListNode<D>>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct RecursiveA {
+ b: Box<RecursiveB>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum RecursiveB { A(RecursiveA), }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct RecursiveGenericA<T> {
+ t: T,
+ b: Box<RecursiveGenericB<T>>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum RecursiveGenericB<T> { T(T), A(RecursiveGenericA<T>), }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct OptionStatic<'a> {
+ a: Option<&'a str>,
+ b: Option<&'static str>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(bound = "D: SerializeWith + DeserializeWith")]
+ #[derive(Deserialize)]
+ 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,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(bound(serialize = "D: SerializeWith",
+ deserialize = "D: DeserializeWith"))]
+ #[derive(Deserialize)]
+ 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,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct CowStr<'a>(Cow<'a, str>);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[serde(bound(deserialize = "T::Owned: Deserialize"))]
+ #[derive(Deserialize)]
+ struct CowT < 'a , T : ? Sized + 'a + ToOwned > ( Cow < 'a , T > ) ;
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct DeNamedTuple<A, B, C>(A, B, C);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
+ a: &'a A,
+ b: &'b mut B,
+ c: C,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ struct DeNamedMap<A, B, C> {
+ a: A,
+ b: < Vec < T > as a :: b :: Trait > :: AssociatedItem,
+ c: < Vec < T > > :: AssociatedItem,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ enum SerEnum<'a, B: 'a, C: 'a, D> where for < 'a > D: 'a {
+ Unit,
+ Seq(i8, B, &'a C, &'a mut D),
+ Map {
+ a: i8,
+ b: B,
+ c: &'a C,
+ d: &'a mut D,
+ },
+ _Unit2,
+ _Seq2(i8, B, &'a C, &'a mut D),
+ _Map2 {
+ a: i8,
+ b: B,
+ c: &'a C,
+ d: &'a mut D,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ enum DeEnum<B, C, D> {
+ Unit,
+ Seq(i8, B, C, D),
+ Map {
+ a: i8,
+ b: B,
+ c: C,
+ d: D,
+ },
+ _Unit2,
+ _Seq2(i8, B, C, D),
+ _Map2 {
+ a: i8,
+ b: B,
+ c: C,
+ d: D,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ enum Lifetimes<'a> {
+ LifetimeSeq(&'a i32),
+ NoLifetimeSeq(i32),
+ LifetimeMap {
+ a: &'a i32,
+ },
+ NoLifetimeMap {
+ a: i32,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ pub struct GenericStruct<T> {
+ x: T,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ pub struct GenericNewTypeStruct<T>(T);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ pub struct GenericTupleStruct<T, U>(T, U);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ pub enum GenericEnum<T, U: for < 'a > F<'a>> {
+ Unit,
+ NewType(T),
+ Seq(T, U),
+ Map {
+ x: T,
+ y: U,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
+ phantom: std :: marker :: PhantomData<T>,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct UnitStruct;
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct TupleStruct(i32, i32, i32);
+ "#,
+ r#"
+ #[derive(Serialize)]
+ struct Struct {
+ a: i32,
+ b: i32,
+ c: i32,
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ enum Enum {
+ Unit,
+ One(i32),
+ Seq(i32, i32),
+ Map {
+ a: i32,
+ b: i32,
+ },
+ }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct Bounds<T: Serialize + Deserialize> {
+ t: T,
+ option: Option<T>,
+ boxed: Box<T>,
+ option_boxed: Option<Box<T>>,
+ }
+ "#,
+ r#"
+ #[derive(Deserialize)]
+ #[rustc_copy_clone_marker]
+ struct UnitStruct;
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[allow(dead_code)]
+ #[deny(unused_variables)]
+ enum Void { }
+ "#,
+ r#"
+ #[derive(Serialize)]
+ #[derive(Deserialize)]
+ struct NamedUnit;
+ "#,
+ ];
+}