From 1af950401c74e9a385dbae104ae665a7797b3a79 Mon Sep 17 00:00:00 2001 From: Magnus Hallin <mhallin@fastmail.com> Date: Fri, 6 Jan 2017 13:08:39 +0100 Subject: [PATCH] Add support for declaring input objects as public structs Fixes #5. --- src/macros/input_object.rs | 63 +++++++++++++++++++++++++------- src/macros/tests/input_object.rs | 34 ++++++++++++++++- src/macros/tests/mod.rs | 5 +++ 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/macros/input_object.rs b/src/macros/input_object.rs index a469d8f3..a7b8067d 100644 --- a/src/macros/input_object.rs +++ b/src/macros/input_object.rs @@ -64,10 +64,10 @@ macro_rules! graphql_input_object { // Generate the struct declaration, including (Rust) meta attributes ( @generate_struct_fields, - ( $($meta:tt)* ), $name:tt, + ( $($meta:tt)* ), ( $($pubmod:tt)* ), $name:tt, ( $($field_name:ident : $field_type:ty $(as $descr:tt)* $(,)* ),* ) ) => { - $($meta)* struct $name { + $($meta)* $($pubmod)* struct $name { $( $field_name: $field_type, )* } }; @@ -93,12 +93,26 @@ macro_rules! graphql_input_object { // struct $name { ... } ( @parse, - ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $descr:tt ), + ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $_ignore5:tt, $descr:tt ), $(#[$meta:meta])* struct $name:ident { $($fields:tt)* } $($rest:tt)* ) => { graphql_input_object!( @parse, - ( ( $(#[$meta])* ), $name, (stringify!($name)), ($($fields)*), $descr ), + ( ( $(#[$meta])* ), ( ), $name, (stringify!($name)), ($($fields)*), $descr ), + $($rest)* + ); + }; + + // #[...] pub struct $name { ... } + // pub struct $name { ... } + ( + @parse, + ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $_ignore5:tt, $descr:tt ), + $(#[$meta:meta])* pub struct $name:ident { $($fields:tt)* } $($rest:tt)* + ) => { + graphql_input_object!( + @parse, + ( ( $(#[$meta])* ), ( pub ), $name, (stringify!($name)), ($($fields)*), $descr ), $($rest)* ); }; @@ -107,12 +121,26 @@ macro_rules! graphql_input_object { // struct $name as "GraphQLName" { ... } ( @parse, - ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $descr:tt ), + ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $_ignore5:tt, $descr:tt ), $(#[$meta:meta])* struct $name:ident as $outname:tt { $($fields:tt)* } $($rest:tt)* ) => { graphql_input_object!( @parse, - ( ( $($meta)* ), $name, $outname, ($($fields)*), $descr ), + ( ( $($meta)* ), ( ), $name, $outname, ($($fields)*), $descr ), + $($rest)* + ); + }; + + // #[...] pub struct $name as "GraphQLName" { ... } + // pub struct $name as "GraphQLName" { ... } + ( + @parse, + ( $_ignore1:tt, $_ignore2:tt, $_ignore3:tt, $_ignore4:tt, $_ignore5:tt, $descr:tt ), + $(#[$meta:meta])* pub struct $name:ident as $outname:tt { $($fields:tt)* } $($rest:tt)* + ) => { + graphql_input_object!( + @parse, + ( ( $($meta)* ), ( pub ), $name, $outname, ($($fields)*), $descr ), $($rest)* ); }; @@ -120,12 +148,12 @@ macro_rules! graphql_input_object { // description: <description> ( @parse, - ( $meta:tt, $name:tt, $outname:tt, $fields:tt, $_ignore:tt ), + ( $meta:tt, $pubmod:tt, $name:tt, $outname:tt, $fields:tt, $_ignore:tt ), description: $descr:tt $($rest:tt)* ) => { graphql_input_object!( @parse, - ( $meta, $name, $outname, $fields, $descr ), + ( $meta, $pubmod, $name, $outname, $fields, $descr ), $($rest)* ); }; @@ -133,9 +161,9 @@ macro_rules! graphql_input_object { // No more data to parse, generate the struct and impls ( @parse, - ( $meta:tt, $name:tt, $outname:tt, $fields:tt, $descr:tt ), + ( $meta:tt, $pubmod:tt, $name:tt, $outname:tt, $fields:tt, $descr:tt ), ) => { - graphql_input_object!(@generate_struct_fields, $meta, $name, $fields); + graphql_input_object!(@generate_struct_fields, $meta, $pubmod, $name, $fields); impl $crate::FromInputValue for $name { fn from(value: &$crate::InputValue) -> Option<$name> { @@ -164,20 +192,29 @@ macro_rules! graphql_input_object { } }; - // Entry point: parse calls starting with the struct declaration + // Entry point: parse calls starting with a struct declaration ( $(#[$meta:meta])* struct $($items:tt)* ) => { graphql_input_object!( @parse, - ( ( ), None, None, None, None ), + ( ( ), ( ), None, None, None, None ), $(#[$meta])* struct $($items)* ); }; + // Entry point: parse calls starting with a public struct declaration + ( $(#[$meta:meta])* pub struct $($items:tt)* ) => { + graphql_input_object!( + @parse, + ( ( ), ( ), None, None, None, None ), + $(#[$meta])* pub struct $($items)* + ); + }; + // Entry point: parse calls starting with the description ( description: $($items:tt)* ) => { graphql_input_object!( @parse, - ( ( ), None, None, None, None ), + ( ( ), ( ), None, None, None, None ), description: $($items)* ); }; diff --git a/src/macros/tests/input_object.rs b/src/macros/tests/input_object.rs index 3999a201..f196ded7 100644 --- a/src/macros/tests/input_object.rs +++ b/src/macros/tests/input_object.rs @@ -42,6 +42,34 @@ graphql_input_object!( } ); +graphql_input_object!( + pub struct Public { + field_one: String, + } +); + +graphql_input_object!( + description: "Description for the input object" + + pub struct PublicWithDescription { + field_one: String, + } +); + +graphql_input_object!( + description: "Description for the input object" + + pub struct NamedPublicWithDescription as "APublicNamedInputObjectWithDescription" { + field_one: String, + } +); + +graphql_input_object!( + pub struct NamedPublic as "APublicNamedInputObject" { + field_one: String, + } +); + graphql_input_object!( struct FieldDescription { field_one: String as "The first field", @@ -56,7 +84,11 @@ graphql_object!(Root: () |&self| { a3: Derive, a4: Named, a5: Description, - a6: FieldDescription + a6: FieldDescription, + a7: Public, + a8: PublicWithDescription, + a9: NamedPublicWithDescription, + a10: NamedPublic, ) -> i64 { 0 } diff --git a/src/macros/tests/mod.rs b/src/macros/tests/mod.rs index a0831de9..b67cd409 100644 --- a/src/macros/tests/mod.rs +++ b/src/macros/tests/mod.rs @@ -6,3 +6,8 @@ mod field; mod object; mod interface; mod union; + + +// This asserts that the input objects defined public actually became public +#[allow(unused_imports)] +use self::input_object::{NamedPublic, NamedPublicWithDescription};