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); +} diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 050c6a1..64b676d 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 }; }) } }