async_graphql_derive/
lib.rs

1#![allow(clippy::cognitive_complexity)]
2#![allow(clippy::vec_init_then_push)]
3#![allow(clippy::uninlined_format_args)]
4#![forbid(unsafe_code)]
5
6extern crate proc_macro;
7
8mod args;
9mod complex_object;
10mod description;
11mod directive;
12mod r#enum;
13mod input_object;
14mod interface;
15mod merged_object;
16mod merged_subscription;
17mod newtype;
18mod object;
19mod oneof_object;
20mod output_type;
21mod scalar;
22mod simple_object;
23mod subscription;
24mod type_directive;
25mod union;
26mod utils;
27mod validators;
28
29use darling::{FromDeriveInput, FromMeta};
30use proc_macro::TokenStream;
31use syn::{parse_macro_input, DeriveInput, ItemFn, ItemImpl};
32
33macro_rules! parse_nested_meta {
34    ($ty:ty, $args:expr) => {{
35        let meta = match darling::ast::NestedMeta::parse_meta_list(proc_macro2::TokenStream::from(
36            $args,
37        )) {
38            Ok(v) => v,
39            Err(e) => {
40                return TokenStream::from(darling::Error::from(e).write_errors());
41            }
42        };
43
44        match <$ty>::from_list(&meta) {
45            Ok(object_args) => object_args,
46            Err(err) => return TokenStream::from(err.write_errors()),
47        }
48    }};
49}
50
51#[proc_macro_attribute]
52#[allow(non_snake_case)]
53pub fn Object(args: TokenStream, input: TokenStream) -> TokenStream {
54    let object_args = parse_nested_meta!(args::Object, args);
55    let mut item_impl = parse_macro_input!(input as ItemImpl);
56    match object::generate(&object_args, &mut item_impl) {
57        Ok(expanded) => expanded,
58        Err(err) => err.write_errors().into(),
59    }
60}
61
62#[proc_macro_derive(SimpleObject, attributes(graphql))]
63pub fn derive_simple_object(input: TokenStream) -> TokenStream {
64    let object_args =
65        match args::SimpleObject::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
66            Ok(object_args) => object_args,
67            Err(err) => return TokenStream::from(err.write_errors()),
68        };
69    match simple_object::generate(&object_args) {
70        Ok(expanded) => expanded,
71        Err(err) => err.write_errors().into(),
72    }
73}
74
75#[proc_macro_attribute]
76#[allow(non_snake_case)]
77pub fn ComplexObject(args: TokenStream, input: TokenStream) -> TokenStream {
78    let object_args = parse_nested_meta!(args::ComplexObject, args);
79    let mut item_impl = parse_macro_input!(input as ItemImpl);
80    match complex_object::generate(&object_args, &mut item_impl) {
81        Ok(expanded) => expanded,
82        Err(err) => err.write_errors().into(),
83    }
84}
85
86#[proc_macro_derive(Enum, attributes(graphql))]
87pub fn derive_enum(input: TokenStream) -> TokenStream {
88    let enum_args = match args::Enum::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
89        Ok(enum_args) => enum_args,
90        Err(err) => return TokenStream::from(err.write_errors()),
91    };
92    match r#enum::generate(&enum_args) {
93        Ok(expanded) => expanded,
94        Err(err) => err.write_errors().into(),
95    }
96}
97
98#[proc_macro_derive(InputObject, attributes(graphql))]
99pub fn derive_input_object(input: TokenStream) -> TokenStream {
100    let object_args =
101        match args::InputObject::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
102            Ok(object_args) => object_args,
103            Err(err) => return TokenStream::from(err.write_errors()),
104        };
105    match input_object::generate(&object_args) {
106        Ok(expanded) => expanded,
107        Err(err) => err.write_errors().into(),
108    }
109}
110
111#[proc_macro_derive(Interface, attributes(graphql))]
112pub fn derive_interface(input: TokenStream) -> TokenStream {
113    let interface_args =
114        match args::Interface::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
115            Ok(interface_args) => interface_args,
116            Err(err) => return TokenStream::from(err.write_errors()),
117        };
118    match interface::generate(&interface_args) {
119        Ok(expanded) => expanded,
120        Err(err) => err.write_errors().into(),
121    }
122}
123
124#[proc_macro_derive(Union, attributes(graphql))]
125pub fn derive_union(input: TokenStream) -> TokenStream {
126    let union_args = match args::Union::from_derive_input(&parse_macro_input!(input as DeriveInput))
127    {
128        Ok(union_args) => union_args,
129        Err(err) => return TokenStream::from(err.write_errors()),
130    };
131    match union::generate(&union_args) {
132        Ok(expanded) => expanded,
133        Err(err) => err.write_errors().into(),
134    }
135}
136
137#[proc_macro_attribute]
138#[allow(non_snake_case)]
139pub fn Subscription(args: TokenStream, input: TokenStream) -> TokenStream {
140    let object_args = parse_nested_meta!(args::Subscription, args);
141    let mut item_impl = parse_macro_input!(input as ItemImpl);
142    match subscription::generate(&object_args, &mut item_impl) {
143        Ok(expanded) => expanded,
144        Err(err) => err.write_errors().into(),
145    }
146}
147
148#[proc_macro_attribute]
149#[allow(non_snake_case)]
150pub fn Scalar(args: TokenStream, input: TokenStream) -> TokenStream {
151    let scalar_args = parse_nested_meta!(args::Scalar, args);
152    let mut item_impl = parse_macro_input!(input as ItemImpl);
153    match scalar::generate(&scalar_args, &mut item_impl) {
154        Ok(expanded) => expanded,
155        Err(err) => err.write_errors().into(),
156    }
157}
158
159#[proc_macro_derive(MergedObject, attributes(graphql))]
160pub fn derive_merged_object(input: TokenStream) -> TokenStream {
161    let object_args =
162        match args::MergedObject::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
163            Ok(object_args) => object_args,
164            Err(err) => return TokenStream::from(err.write_errors()),
165        };
166    match merged_object::generate(&object_args) {
167        Ok(expanded) => expanded,
168        Err(err) => err.write_errors().into(),
169    }
170}
171
172#[proc_macro_derive(MergedSubscription, attributes(graphql))]
173pub fn derive_merged_subscription(input: TokenStream) -> TokenStream {
174    let object_args = match args::MergedSubscription::from_derive_input(&parse_macro_input!(
175        input as DeriveInput
176    )) {
177        Ok(object_args) => object_args,
178        Err(err) => return TokenStream::from(err.write_errors()),
179    };
180    match merged_subscription::generate(&object_args) {
181        Ok(expanded) => expanded,
182        Err(err) => err.write_errors().into(),
183    }
184}
185
186#[proc_macro_derive(Description, attributes(graphql))]
187pub fn derive_description(input: TokenStream) -> TokenStream {
188    let desc_args =
189        match args::Description::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
190            Ok(desc_args) => desc_args,
191            Err(err) => return TokenStream::from(err.write_errors()),
192        };
193    match description::generate(&desc_args) {
194        Ok(expanded) => expanded,
195        Err(err) => err.write_errors().into(),
196    }
197}
198
199#[proc_macro_derive(NewType, attributes(graphql))]
200pub fn derive_newtype(input: TokenStream) -> TokenStream {
201    let newtype_args =
202        match args::NewType::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
203            Ok(newtype_args) => newtype_args,
204            Err(err) => return TokenStream::from(err.write_errors()),
205        };
206    match newtype::generate(&newtype_args) {
207        Ok(expanded) => expanded,
208        Err(err) => err.write_errors().into(),
209    }
210}
211
212#[proc_macro_attribute]
213#[allow(non_snake_case)]
214pub fn Directive(args: TokenStream, input: TokenStream) -> TokenStream {
215    let directive_args = parse_nested_meta!(args::Directive, args);
216    let mut item_fn = parse_macro_input!(input as ItemFn);
217    match directive::generate(&directive_args, &mut item_fn) {
218        Ok(expanded) => expanded,
219        Err(err) => err.write_errors().into(),
220    }
221}
222
223#[proc_macro_attribute]
224#[allow(non_snake_case)]
225pub fn TypeDirective(args: TokenStream, input: TokenStream) -> TokenStream {
226    let directive_args = parse_nested_meta!(args::TypeDirective, args);
227    let mut item_fn = parse_macro_input!(input as ItemFn);
228    match type_directive::generate(&directive_args, &mut item_fn) {
229        Ok(expanded) => expanded,
230        Err(err) => err.write_errors().into(),
231    }
232}
233
234#[proc_macro_derive(OneofObject, attributes(graphql))]
235pub fn derive_oneof_object(input: TokenStream) -> TokenStream {
236    let object_args =
237        match args::OneofObject::from_derive_input(&parse_macro_input!(input as DeriveInput)) {
238            Ok(object_args) => object_args,
239            Err(err) => return TokenStream::from(err.write_errors()),
240        };
241    match oneof_object::generate(&object_args) {
242        Ok(expanded) => expanded,
243        Err(err) => err.write_errors().into(),
244    }
245}