Skip to main content

cynic_codegen/input_object_derive/
mod.rs

1use proc_macro2::{Span, TokenStream};
2
3use crate::{
4    error::Errors,
5    idents::RenameAll,
6    input_object_derive::{
7        one_of::oneof_input_object_derive, standard::standard_input_object_derive,
8    },
9    schema::{Schema, types::InputObjectType},
10};
11
12mod one_of;
13mod standard;
14
15pub(crate) mod input;
16
17mod pairing;
18#[cfg(test)]
19mod tests;
20
21pub use input::InputObjectDeriveInput;
22
23pub fn input_object_derive(ast: &syn::DeriveInput) -> Result<TokenStream, syn::Error> {
24    use darling::FromDeriveInput;
25
26    let struct_span = ast.ident.span();
27
28    match InputObjectDeriveInput::from_derive_input(ast) {
29        Ok(input) => {
30            input_object_derive_impl(input, struct_span).or_else(|e| Ok(e.to_compile_errors()))
31        }
32        Err(e) => Ok(e.write_errors()),
33    }
34}
35
36pub fn input_object_derive_impl(
37    input: InputObjectDeriveInput,
38    struct_span: Span,
39) -> Result<TokenStream, Errors> {
40    let schema = Schema::new(input.schema_input()?);
41
42    let input_object = schema
43        .lookup::<InputObjectType<'_>>(&input.graphql_type_name())
44        .map_err(|e| syn::Error::new(input.graphql_type_span(), e))?;
45
46    let rename_all = input.rename_all.unwrap_or(RenameAll::CamelCase);
47
48    match &input.data {
49        darling::ast::Data::Enum(variants) => {
50            if input_object.fields.iter().any(|field| !field.is_nullable()) {
51                return Err(syn::Error::new(
52                    struct_span,
53                    "An enum can only represent an InputObject when all of the input fields are nullable".to_string(),
54                )
55                .into());
56            }
57            oneof_input_object_derive(
58                &input,
59                struct_span,
60                &schema,
61                input_object,
62                rename_all,
63                variants,
64            )
65        }
66        darling::ast::Data::Struct(fields) => standard_input_object_derive(
67            &input,
68            struct_span,
69            &schema,
70            input_object,
71            rename_all,
72            fields,
73        ),
74    }
75}