use super::shared::keyword_replace;
use crate::{
codegen_options::GraphQLClientCodegenOptions,
query::{BoundQuery, UsedTypes},
schema::input_is_recursive_without_indirection,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
pub(super) fn generate_input_object_definitions(
all_used_types: &UsedTypes,
options: &GraphQLClientCodegenOptions,
variable_derives: &impl quote::ToTokens,
query: &BoundQuery<'_>,
) -> Vec<TokenStream> {
all_used_types
.inputs(query.schema)
.map(|(_input_id, input)| {
let normalized_name = options.normalization().input_name(input.name.as_str());
let safe_name = keyword_replace(normalized_name);
let struct_name = Ident::new(safe_name.as_ref(), Span::call_site());
let fields = input.fields.iter().map(|(field_name, field_type)| {
let safe_field_name = keyword_replace(field_name);
let name_ident = Ident::new(safe_field_name.as_ref(), Span::call_site());
let normalized_field_type_name = options
.normalization()
.field_type(field_type.id.name(query.schema));
let type_name = Ident::new(normalized_field_type_name.as_ref(), Span::call_site());
let field_type_tokens = super::decorate_type(&type_name, &field_type.qualifiers);
let field_type = if field_type
.id
.as_input_id()
.map(|input_id| input_is_recursive_without_indirection(input_id, query.schema))
.unwrap_or(false)
{
quote!(Box<#field_type_tokens>)
} else {
field_type_tokens
};
quote!(pub #name_ident: #field_type)
});
quote! {
#variable_derives
pub struct #struct_name {
#(#fields,)*
}
}
})
.collect()
}