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}