diff --git a/graphql_client/tests/skip_serializing_none.rs b/graphql_client/tests/skip_serializing_none.rs index 0d261847..bf177da4 100644 --- a/graphql_client/tests/skip_serializing_none.rs +++ b/graphql_client/tests/skip_serializing_none.rs @@ -13,6 +13,10 @@ fn skip_serializing_none() { use skip_serializing_none_mutation::*; let query = SkipSerializingNoneMutation::build_query(Variables { + optional_int: None, + optional_list: None, + non_optional_int: 1337, + non_optional_list: vec![], param: Some(Param { data: Author { name: "test".to_owned(), @@ -25,5 +29,29 @@ fn skip_serializing_none() { println!("{}", stringified); - assert!(stringified.contains(r#""data":{"name":"test"}"#)); + assert!(stringified.contains(r#""param":{"data":{"name":"test"}}"#)); + assert!(stringified.contains(r#""nonOptionalInt":1337"#)); + assert!(stringified.contains(r#""nonOptionalList":[]"#)); + assert!(!stringified.contains(r#""optionalInt""#)); + assert!(!stringified.contains(r#""optionalList""#)); + + let query = SkipSerializingNoneMutation::build_query(Variables { + optional_int: Some(42), + optional_list: Some(vec![]), + non_optional_int: 1337, + non_optional_list: vec![], + param: Some(Param { + data: Author { + name: "test".to_owned(), + id: None, + }, + }), + }); + let stringified = serde_json::to_string(&query).expect("SkipSerializingNoneMutation is valid"); + println!("{}", stringified); + assert!(stringified.contains(r#""param":{"data":{"name":"test"}}"#)); + assert!(stringified.contains(r#""nonOptionalInt":1337"#)); + assert!(stringified.contains(r#""nonOptionalList":[]"#)); + assert!(stringified.contains(r#""optionalInt":42"#)); + assert!(stringified.contains(r#""optionalList":[]"#)); } diff --git a/graphql_client/tests/skip_serializing_none/query.graphql b/graphql_client/tests/skip_serializing_none/query.graphql index 028ae768..a91b798f 100644 --- a/graphql_client/tests/skip_serializing_none/query.graphql +++ b/graphql_client/tests/skip_serializing_none/query.graphql @@ -1,4 +1,4 @@ -mutation SkipSerializingNoneMutation($param: Param) { +mutation SkipSerializingNoneMutation($param: Param, $optionalInt: Int, $optionalList: [Int!], $nonOptionalInt: Int!, $nonOptionalList: [Int!]!) { optInput(query: $param) { name __typename diff --git a/graphql_client_codegen/src/codegen.rs b/graphql_client_codegen/src/codegen.rs index f3ad1a94..3ea1235e 100644 --- a/graphql_client_codegen/src/codegen.rs +++ b/graphql_client_codegen/src/codegen.rs @@ -135,10 +135,19 @@ fn generate_variable_struct_field( let snake_case_name = variable.name.to_snake_case(); let safe_name = shared::keyword_replace(&snake_case_name); let ident = Ident::new(&safe_name, Span::call_site()); - let annotation = shared::field_rename_annotation(&variable.name, &safe_name); + let rename_annotation = shared::field_rename_annotation(&variable.name, &safe_name); + let skip_serializing_annotation = if *options.skip_serializing_none() { + if variable.r#type.qualifiers.first() != Some(&GraphqlTypeQualifier::Required) { + Some(quote!(#[serde(skip_serializing_if = "Option::is_none")])) + } else { + None + } + } else { + None + }; let r#type = render_variable_field_type(variable, options, query); - quote::quote!(#annotation pub #ident : #r#type) + quote::quote!(#skip_serializing_annotation #rename_annotation pub #ident : #r#type) } fn generate_scalar_definitions<'a, 'schema: 'a>(