1
1
use crate :: util;
2
2
use proc_macro:: TokenStream ;
3
+ use proc_macro_error:: * ;
3
4
use quote:: quote;
5
+ use syn:: spanned:: Spanned ;
4
6
5
7
/// Generate code for the juniper::object macro.
6
8
pub fn build_object ( args : TokenStream , body : TokenStream , is_internal : bool ) -> TokenStream {
@@ -101,7 +103,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
101
103
}
102
104
} ;
103
105
104
- let attrs = match util:: FieldAttributes :: from_attrs (
106
+ let mut attrs = match util:: FieldAttributes :: from_attrs (
105
107
method. attrs ,
106
108
util:: FieldAttributeParseMode :: Impl ,
107
109
) {
@@ -112,6 +114,16 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
112
114
) ,
113
115
} ;
114
116
117
+ if !attrs. arguments . is_empty ( ) {
118
+ let deprecation_warning = vec ! [
119
+ "Setting arguments via #[graphql(arguments(...))] on the method" ,
120
+ "is deprecrated. Instead use #[graphql(...)] as attributes directly" ,
121
+ "on the arguments themselves." ,
122
+ ]
123
+ . join ( " " ) ;
124
+ eprintln ! ( "{}" , deprecation_warning) ;
125
+ }
126
+
115
127
let mut args = Vec :: new ( ) ;
116
128
let mut resolve_parts = Vec :: new ( ) ;
117
129
@@ -126,6 +138,12 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
126
138
}
127
139
}
128
140
syn:: FnArg :: Typed ( ref captured) => {
141
+ if let Some ( field_arg) = parse_argument_attrs ( & captured) {
142
+ attrs
143
+ . arguments
144
+ . insert ( field_arg. name . to_string ( ) , field_arg) ;
145
+ }
146
+
129
147
let ( arg_ident, is_mut) = match & * captured. pat {
130
148
syn:: Pat :: Ident ( ref pat_ident) => {
131
149
( & pat_ident. ident , pat_ident. mutability . is_some ( ) )
@@ -224,3 +242,45 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
224
242
let juniper_crate_name = if is_internal { "crate" } else { "juniper" } ;
225
243
definition. into_tokens ( juniper_crate_name) . into ( )
226
244
}
245
+
246
+ fn parse_argument_attrs ( pat : & syn:: PatType ) -> Option < util:: FieldAttributeArgument > {
247
+ let graphql_attrs = pat
248
+ . attrs
249
+ . iter ( )
250
+ . filter ( |attr| {
251
+ let name = attr. path . get_ident ( ) . map ( |i| i. to_string ( ) ) ;
252
+ name == Some ( "graphql" . to_string ( ) )
253
+ } )
254
+ . collect :: < Vec < _ > > ( ) ;
255
+
256
+ let graphql_attr = match graphql_attrs. len ( ) {
257
+ 0 => return None ,
258
+ 1 => & graphql_attrs[ 0 ] ,
259
+ _ => {
260
+ let last_attr = graphql_attrs. last ( ) . unwrap ( ) ;
261
+ abort ! (
262
+ last_attr. span( ) ,
263
+ "You cannot have multiple #[graphql] attributes on the same arg"
264
+ ) ;
265
+ }
266
+ } ;
267
+
268
+ let name = match & * pat. pat {
269
+ syn:: Pat :: Ident ( i) => & i. ident ,
270
+ other => unimplemented ! ( "{:?}" , other) ,
271
+ } ;
272
+
273
+ let mut arg = util:: FieldAttributeArgument {
274
+ name : name. to_owned ( ) ,
275
+ default : None ,
276
+ description : None ,
277
+ } ;
278
+
279
+ graphql_attr
280
+ . parse_args_with ( |content : syn:: parse:: ParseStream | {
281
+ util:: parse_field_attr_arg_contents ( & content, & mut arg)
282
+ } )
283
+ . unwrap_or_else ( |err| abort ! ( err. span( ) , "{}" , err) ) ;
284
+
285
+ Some ( arg)
286
+ }
0 commit comments