cynic_codegen/query_variable_literals_derive/
mod.rs

1use {proc_macro2::TokenStream, quote::quote};
2
3mod input;
4
5use crate::generics_for_serde;
6
7use self::input::QueryVariableLiteralsInput;
8
9pub fn query_variable_literals_derive(ast: &syn::DeriveInput) -> Result<TokenStream, syn::Error> {
10    use darling::FromDeriveInput;
11
12    match QueryVariableLiteralsInput::from_derive_input(ast) {
13        Ok(input) => inlineable_variables_derive_impl(input),
14        Err(e) => Ok(e.write_errors()),
15    }
16}
17
18pub fn inlineable_variables_derive_impl(
19    input: QueryVariableLiteralsInput,
20) -> Result<TokenStream, syn::Error> {
21    let ident = &input.ident;
22
23    let (_, ty_generics, _) = input.generics.split_for_impl();
24    let generics_with_ser = generics_for_serde::with_serialize_bounds(&input.generics);
25    let (impl_generics_with_ser, _, where_clause_with_ser) = generics_with_ser.split_for_impl();
26
27    let input_fields = input.data.take_struct().unwrap().fields;
28
29    let mut match_arms = Vec::new();
30
31    for f in input_fields {
32        let name = f.ident.as_ref().unwrap();
33
34        let name_str =
35            proc_macro2::Literal::string(&f.graphql_ident(input.rename_all).graphql_name());
36
37        let mut match_arm_rhs =
38            quote! { Some(cynic::queries::to_input_literal(&self.#name).ok()?) };
39
40        if let Some(skip_check_fn) = f.skip_serializing_if {
41            let skip_check_fn = &*skip_check_fn;
42            match_arm_rhs = quote! {
43                if #skip_check_fn(&self.#name) {
44                    None
45                } else {
46                    #match_arm_rhs
47                }
48            }
49        }
50
51        match_arms.push(quote! {
52            #name_str => #match_arm_rhs,
53        })
54    }
55
56    Ok(quote! {
57        #[automatically_derived]
58        impl #impl_generics_with_ser cynic::QueryVariableLiterals for #ident #ty_generics #where_clause_with_ser {
59            fn get(&self, variable_name: &str) -> Option<cynic::queries::InputLiteral> {
60                match variable_name {
61                    #(#match_arms)*
62                    _ => None
63                }
64            }
65        }
66    })
67}