From 0139d63f6dae7128af4a3f25c347b4568096e5d2 Mon Sep 17 00:00:00 2001 From: olvyko Date: Thu, 29 Apr 2021 21:39:47 +0600 Subject: [PATCH 1/2] Alter yaserde_derive crate to support skip_serialize_if for attributes --- yaserde_derive/src/common/field.rs | 9 +++++++-- yaserde_derive/src/lib.rs | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 9cdb65e..35a8850 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -145,13 +145,18 @@ impl YaSerdeField { .map(|builder| quote!(let yaserde_inner = #builder;)) .unwrap_or_default(); + let skip_if = self + .get_skip_serializing_if_function() + .map(|skip_if_function| quote!(!self.#skip_if_function(&self.#label))) + .unwrap_or(quote!(true)); + self .get_default_function() .map(|default_function| { quote! { #yaserde_inner_definition let struct_start_event = - if self.#label != #default_function() { + if #skip_if && self.#label != #default_function() { #setter } else { struct_start_event @@ -160,7 +165,7 @@ impl YaSerdeField { }) .unwrap_or(quote! { #yaserde_inner_definition - let struct_start_event = #setter; + let struct_start_event = if #skip_if { #setter } else { struct_start_event }; }) } } diff --git a/yaserde_derive/src/lib.rs b/yaserde_derive/src/lib.rs index f09ab20..9d881a1 100644 --- a/yaserde_derive/src/lib.rs +++ b/yaserde_derive/src/lib.rs @@ -14,7 +14,7 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); match de::expand_derive_deserialize(&ast) { Ok(expanded) => expanded.into(), - Err(msg) => panic!(msg), + Err(msg) => panic!("{}", msg), } } @@ -23,6 +23,6 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); match ser::expand_derive_serialize(&ast) { Ok(expanded) => expanded.into(), - Err(msg) => panic!(msg), + Err(msg) => panic!("{}", msg), } } From cb25872cde2af5645c79e61b28b9f90d4bbab6fb Mon Sep 17 00:00:00 2001 From: olvyko Date: Thu, 29 Apr 2021 22:10:52 +0600 Subject: [PATCH 2/2] Add test for attribute with skip_serialize_if --- yaserde/tests/skip_if.rs | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/yaserde/tests/skip_if.rs b/yaserde/tests/skip_if.rs index a485a8f..6bb7910 100644 --- a/yaserde/tests/skip_if.rs +++ b/yaserde/tests/skip_if.rs @@ -62,3 +62,60 @@ fn skip_serializing_if_for_struct() { let content = ""; serialize_and_validate!(model, content); } + +#[test] +fn skip_serializing_if_for_struct_attributes() { + init(); + + fn default_string_function() -> String { + "mask_default".to_string() + } + + #[derive(YaSerialize, PartialEq, Debug)] + #[yaserde(rename = "base")] + pub struct XmlStruct { + #[yaserde( + attribute, + skip_serializing_if = "check_string_function", + default = "default_string_function" + )] + string_with_default_item: String, + #[yaserde(attribute, skip_serializing_if = "check_string_function")] + string_item: String, + #[yaserde(attribute, skip_serializing_if = "check_bool_function")] + bool_item: bool, + #[yaserde(attribute, skip_serializing_if = "check_f32_function")] + f32_item: f32, + #[yaserde(attribute, skip_serializing_if = "check_option_string_function")] + option_string_item: Option, + } + + impl XmlStruct { + fn check_string_function(&self, value: &str) -> bool { + value == "something" + } + + fn check_option_string_function(&self, value: &Option) -> bool { + value == &Some("something".to_string()) + } + + fn check_bool_function(&self, value: &bool) -> bool { + value == &true + } + + fn check_f32_function(&self, value: &f32) -> bool { + (value - 0.0).abs() < std::f32::EPSILON + } + } + + let model = XmlStruct { + string_with_default_item: "mask_default".to_string(), + string_item: "something".to_string(), + bool_item: true, + f32_item: 0.0, + option_string_item: Some("something".to_string()), + }; + + let content = ""; + serialize_and_validate!(model, content); +}