Skip to content

Commit 39772fd

Browse files
committed
Finish implementing skip_none
1 parent a79be89 commit 39772fd

File tree

3 files changed

+71
-15
lines changed

3 files changed

+71
-15
lines changed

graphql_client_codegen/src/codegen/inputs.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
codegen_options::GraphQLClientCodegenOptions,
44
query::{BoundQuery, UsedTypes},
55
schema::input_is_recursive_without_indirection,
6+
type_qualifiers::GraphqlTypeQualifier,
67
};
78
use heck::ToSnakeCase;
89
use proc_macro2::{Ident, Span, TokenStream};
@@ -28,6 +29,11 @@ pub(super) fn generate_input_object_definitions(
2829
let normalized_field_type_name = options
2930
.normalization()
3031
.field_type(field_type.id.name(query.schema));
32+
let optional_skip_none = if *options.skip_none() && field_type.is_optional() {
33+
Some(quote!(#[serde(skip_serializing_if = "Option::is_none")]))
34+
} else {
35+
None
36+
};
3137
let type_name = Ident::new(normalized_field_type_name.as_ref(), Span::call_site());
3238
let field_type_tokens = super::decorate_type(&type_name, &field_type.qualifiers);
3339
let field_type = if field_type
@@ -40,23 +46,18 @@ pub(super) fn generate_input_object_definitions(
4046
} else {
4147
field_type_tokens
4248
};
43-
quote!(#annotation pub #name_ident: #field_type)
49+
50+
quote!(
51+
#optional_skip_none
52+
#annotation pub #name_ident: #field_type
53+
)
4454
});
4555

46-
match *options.skip_none() {
47-
true => quote! {
48-
#[serde(skip_serializing_if = "Option::is_none")]
49-
#variable_derives
50-
pub struct #struct_name{
51-
#(#fields,)*
52-
}
53-
},
54-
false => quote! {
55-
#variable_derives
56-
pub struct #struct_name{
57-
#(#fields,)*
58-
}
59-
},
56+
quote! {
57+
#variable_derives
58+
pub struct #struct_name{
59+
#(#fields,)*
60+
}
6061
}
6162
})
6263
.collect()

graphql_client_codegen/src/codegen/selection.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@ impl<'a> ExpandedField<'a> {
405405
qualified_type
406406
};
407407

408+
let optional_skip_none = if *options.skip_none()
409+
&& self
410+
.field_type_qualifiers
411+
.get(0)
412+
.map(|qualifier| !qualifier.is_required())
413+
.unwrap_or(false)
414+
{
415+
Some(quote!(#[serde(skip_serializing_if = "Option::is_none")]))
416+
} else {
417+
None
418+
};
419+
408420
let optional_rename = self
409421
.graphql_name
410422
.as_ref()
@@ -427,6 +439,7 @@ impl<'a> ExpandedField<'a> {
427439
};
428440

429441
let tokens = quote! {
442+
#optional_skip_none
430443
#optional_flatten
431444
#optional_rename
432445
#optional_deprecation_annotation

graphql_client_codegen/src/tests/mod.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,45 @@ fn fragments_other_variant_false_should_not_generate_unknown_other_variant() {
117117
};
118118
}
119119
}
120+
121+
#[test]
122+
fn skip_none_should_generate_serde_skip_serializing() {
123+
let query_string = include_str!("keywords_query.graphql");
124+
let query = graphql_parser::parse_query::<&str>(query_string).expect("Parse keywords query");
125+
let schema = graphql_parser::parse_schema(include_str!("keywords_schema.graphql"))
126+
.expect("Parse keywords schema")
127+
.into_static();
128+
let schema = Schema::from(schema);
129+
130+
let mut options = GraphQLClientCodegenOptions::new(CodegenMode::Cli);
131+
132+
options.set_skip_none(true);
133+
134+
let query = crate::query::resolve(&schema, &query).unwrap();
135+
136+
for (_id, operation) in query.operations() {
137+
let generated_tokens = generated_module::GeneratedModule {
138+
query_string,
139+
schema: &schema,
140+
operation: &operation.name,
141+
resolved_query: &query,
142+
options: &options,
143+
}
144+
.to_token_stream()
145+
.expect("Generate keywords module");
146+
147+
let generated_code = generated_tokens.to_string();
148+
149+
let r: syn::parse::Result<proc_macro2::TokenStream> = syn::parse2(generated_tokens);
150+
151+
match r {
152+
Ok(_) => {
153+
println!("{}", generated_code);
154+
assert!(generated_code.contains("skip_serializing_if"));
155+
}
156+
Err(e) => {
157+
panic!("Error: {}\n Generated content: {}\n", e, &generated_code);
158+
}
159+
};
160+
}
161+
}

0 commit comments

Comments
 (0)