@@ -14,14 +14,10 @@ use syn::{
1414 token,
1515} ;
1616
17- use crate :: common:: {
18- Description , SpanContainer , default, diagnostic, filter_attrs,
19- parse:: {
20- ParseBufferExt as _, TypeExt as _,
21- attr:: { OptionExt as _, err} ,
22- } ,
23- path_eq_single, rename, scalar,
24- } ;
17+ use crate :: common:: { Description , SpanContainer , default, diagnostic, filter_attrs, parse:: {
18+ ParseBufferExt as _, TypeExt as _,
19+ attr:: { OptionExt as _, err} ,
20+ } , path_eq_single, rename, scalar, deprecation} ;
2521
2622/// Available metadata (arguments) behind `#[graphql]` attribute placed on a
2723/// method argument, when generating code for [GraphQL argument][1].
@@ -43,6 +39,15 @@ pub(crate) struct Attr {
4339 /// [2]: https://spec.graphql.org/October2021#sec-Descriptions
4440 pub ( crate ) description : Option < SpanContainer < Description > > ,
4541
42+ /// Explicitly specified [deprecation][2] of this [GraphQL argument][1].
43+ ///
44+ /// If [`None`], then Rust `#[deprecated]` attribute will be used as the [deprecation][2], if
45+ /// any.
46+ ///
47+ /// [1]: https://spec.graphql.org/October2021#sec-Language.Arguments
48+ /// [2]: https://spec.graphql.org/October2021#sec-Deprecation
49+ pub ( crate ) deprecated : Option < SpanContainer < deprecation:: Directive > > ,
50+
4651 /// Explicitly specified [default value][2] of this [GraphQL argument][1].
4752 ///
4853 /// If [`None`], then this [GraphQL argument][1] is considered as
@@ -97,6 +102,16 @@ impl Parse for Attr {
97102 . replace ( SpanContainer :: new ( ident. span ( ) , Some ( desc. span ( ) ) , desc) )
98103 . none_or_else ( |_| err:: dup_arg ( & ident) ) ?
99104 }
105+ "deprecated" => {
106+ let directive = input. parse :: < deprecation:: Directive > ( ) ?;
107+ out. deprecated
108+ . replace ( SpanContainer :: new (
109+ ident. span ( ) ,
110+ directive. reason . as_ref ( ) . map ( |r| r. span ( ) ) ,
111+ directive,
112+ ) )
113+ . none_or_else ( |_| err:: dup_arg ( & ident) ) ?
114+ }
100115 "default" => {
101116 let val = input. parse :: < default:: Value > ( ) ?;
102117 out. default
@@ -132,6 +147,7 @@ impl Attr {
132147 Ok ( Self {
133148 name : try_merge_opt ! ( name: self , another) ,
134149 description : try_merge_opt ! ( description: self , another) ,
150+ deprecated : try_merge_opt ! ( deprecated: self , another) ,
135151 default : try_merge_opt ! ( default : self , another) ,
136152 context : try_merge_opt ! ( context: self , another) ,
137153 executor : try_merge_opt ! ( executor: self , another) ,
@@ -141,13 +157,14 @@ impl Attr {
141157 /// Parses [`Attr`] from the given multiple `name`d [`syn::Attribute`]s
142158 /// placed on a function argument.
143159 pub ( crate ) fn from_attrs ( name : & str , attrs : & [ syn:: Attribute ] ) -> syn:: Result < Self > {
144- let attr = filter_attrs ( name, attrs)
160+ let mut attr = filter_attrs ( name, attrs)
145161 . map ( |attr| attr. parse_args ( ) )
146162 . try_fold ( Self :: default ( ) , |prev, curr| prev. try_merge ( curr?) ) ?;
147163
148164 if let Some ( context) = & attr. context {
149165 if attr. name . is_some ( )
150166 || attr. description . is_some ( )
167+ || attr. deprecated . is_some ( )
151168 || attr. default . is_some ( )
152169 || attr. executor . is_some ( )
153170 {
@@ -161,6 +178,7 @@ impl Attr {
161178 if let Some ( executor) = & attr. executor {
162179 if attr. name . is_some ( )
163180 || attr. description . is_some ( )
181+ || attr. deprecated . is_some ( )
164182 || attr. default . is_some ( )
165183 || attr. context . is_some ( )
166184 {
@@ -171,6 +189,10 @@ impl Attr {
171189 }
172190 }
173191
192+ if attr. deprecated . is_none ( ) && attr. context . is_none ( ) && attr. executor . is_none ( ) {
193+ attr. deprecated = deprecation:: Directive :: parse_from_deprecated_attr ( attrs) ?;
194+ }
195+
174196 Ok ( attr)
175197 }
176198
@@ -229,6 +251,12 @@ pub(crate) struct OnField {
229251 /// [1]: https://spec.graphql.org/October2021#sec-Language.Arguments
230252 /// [2]: https://spec.graphql.org/October2021#sec-Required-Arguments
231253 pub ( crate ) default : Option < default:: Value > ,
254+
255+ /// [Deprecation][2] of this [GraphQL field argument][1] to put into GraphQL schema.
256+ ///
257+ /// [1]: https://spec.graphql.org/October2021#sec-Language.Arguments
258+ /// [2]: https://spec.graphql.org/October2021#sec-Deprecation
259+ pub ( crate ) deprecated : Option < deprecation:: Directive > ,
232260}
233261
234262/// Possible kinds of Rust method arguments for code generation.
@@ -300,6 +328,7 @@ impl OnMethod {
300328 let ( name, ty) = ( & arg. name , & arg. ty ) ;
301329
302330 let description = & arg. description ;
331+ let deprecated = & arg. deprecated ;
303332
304333 let method = if let Some ( val) = & arg. default {
305334 quote_spanned ! { val. span( ) =>
@@ -311,7 +340,7 @@ impl OnMethod {
311340 }
312341 } ;
313342
314- Some ( quote ! { . argument( registry #method #description) } )
343+ Some ( quote ! { . argument( registry #method #description #deprecated ) } )
315344 }
316345
317346 /// Returns generated code for the [`GraphQLValue::resolve_field`] method,
@@ -437,6 +466,7 @@ impl OnMethod {
437466 ty : argument. ty . as_ref ( ) . clone ( ) ,
438467 description : attr. description . map ( SpanContainer :: into_inner) ,
439468 default : attr. default . map ( SpanContainer :: into_inner) ,
469+ deprecated : attr. deprecated . map ( SpanContainer :: into_inner) ,
440470 } ) ) )
441471 }
442472}
0 commit comments