Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for skip_serializing_if / skip_serializing_if is not triggered for enums #139

Open
mracsko opened this issue Apr 7, 2022 · 3 comments

Comments

@mracsko
Copy link
Contributor

mracsko commented Apr 7, 2022

Currently I try to set up skip_serializing_if, but I could not make it work. In the examples I saw some ways to do it, but it still serialize the values. Can you provide some details about usage of this field?

@mracsko
Copy link
Contributor Author

mracsko commented Apr 7, 2022

I have looked into more details and I was checking test cases. It looks like that skip does not work with enum:

use yaserde_derive::YaSerialize;

#[derive(YaSerialize, PartialEq, Debug)]
enum Enum {
    Enum1,
    Enum2,
}

#[derive(YaSerialize, PartialEq, Debug)]
struct Struct {
    #[yaserde(skip_serializing_if = "check_bool")]
    bool_value: bool,
    #[yaserde(skip_serializing_if = "check_string")]
    string_value: String,
    #[yaserde(skip_serializing_if = "check_i32")]
    i32_value: i32,
    #[yaserde(skip_serializing_if = "check_optional_string")]
    optional_string_value: Option<String>,
    #[yaserde(skip_serializing_if = "check_enum")]
    enum_value: Enum,
}

impl Struct {
    fn check_bool(&self, value: &bool) -> bool {
        value == &false
    }

    fn check_string(&self, value: &str) -> bool {
        value == "skip"
    }

    fn check_i32(&self, value: &i32) -> bool {
        value < &10
    }

    fn check_optional_string(&self, value: &Option<String>) -> bool {
        value == &Some("skip".to_string())
    }

    fn check_enum(&self, value: &Enum) -> bool {
        value == &Enum::Enum1
    }
}

fn main() {
    let obj_no_skip = Struct {
        bool_value: true,
        string_value: "testString".to_string(),
        i32_value: 10,
        optional_string_value: Some("optionalTestString".to_string()),
        enum_value: Enum::Enum2,
    };

    let obj_skip_all = Struct {
        bool_value: false,
        string_value: "skip".to_string(),
        i32_value: 9,
        optional_string_value: Some("skip".to_string()),
        enum_value: Enum::Enum1,
    };

    let yaserde_cfg = yaserde::ser::Config::default();

    assert_eq!("<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct><bool_value>true</bool_value><string_value>testString</string_value><i32_value>10</i32_value><optional_string_value>optionalTestString</optional_string_value><enum_value>Enum2</enum_value></Struct>", yaserde::ser::to_string_with_config(&obj_no_skip, &yaserde_cfg).ok().unwrap());
    assert_eq!("<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct></Struct>", yaserde::ser::to_string_with_config(&obj_skip_all, &yaserde_cfg).ok().unwrap());
}

Second assert fails with:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct></Struct>"`,
 right: `"<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct><enum_value>Enum1</enum_value></Struct>"`', src\main.rs:65:5

bug

After more investigation, it looks like that the skip is not called for enum fields at all. This is visible if we add println! for all checks:

impl Struct {
    fn check_bool(&self, value: &bool) -> bool {
        println!("Running 'check_bool'");
        value == &false
    }

    fn check_string(&self, value: &str) -> bool {
        println!("Running 'check_string'");
        value == "skip"
    }

    fn check_i32(&self, value: &i32) -> bool {
        println!("Running 'check_i32'");
        value < &10
    }

    fn check_optional_string(&self, value: &Option<String>) -> bool {
        println!("Running 'check_optional_string'");
        value == &Some("skip".to_string())
    }

    fn check_enum(&self, value: &Enum) -> bool {
        println!("Running 'check_enum'");
        value == &Enum::Enum1
    }
}

Output for the previous example:

Running 'check_bool'
Running 'check_string'
Running 'check_i32'
Running 'check_optional_string'
Running 'check_bool'
Running 'check_string'
Running 'check_i32'
Running 'check_optional_string'
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `"<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct></Struct>"`,
 right: `"<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct><enum_value>Enum1</enum_value></Struct>"`', src\main.rs:70:5

It is visible that all functions are called, except check_enum.

mracsko added a commit to mracsko/yaserde that referenced this issue Apr 7, 2022
@mracsko mracsko changed the title Add documentation for skip_serializing_if Add documentation for skip_serializing_if / skip_serializing_if is not triggered for enums Apr 7, 2022
@mracsko
Copy link
Contributor Author

mracsko commented Apr 7, 2022

Pull request is created for improved documentation, but feedback is required regarding the above mentioned bug.

MarcAntoine-Arnaud added a commit that referenced this issue Apr 11, 2022
#139 Adding documentation for skip_serializing
@lbenini
Copy link
Contributor

lbenini commented Jan 4, 2023

Please note that with the merge of #153 this issue is now solved and the code works as expected with just a small correction

assert_eq!("<?xml version=\"1.0\" encoding=\"utf-8\"?><Struct />", yaserde::ser::to_string_with_config(&obj_skip_all, &yaserde_cfg).ok().unwrap());

because an empty element is serialized by yaserde in self-closing mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants