cynic_codegen/query_variable_literals_derive/
mod.rs1use {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}