lesurp/OptionalStruct

add skip_serializing_if = "Option::is_none" to each value?

Closed this issue · 7 comments

Is there a way to add #[serde(skip_serializing_if = "Option::is_none")] to each member of the optional struct? Or a way to achieve a similar effect?

Currently solving with the below, which kind of moots the point of using OptionalStruct -- almost easier to just to create OptionalConfig manually...

impl Serialize for OptionalConfig {
    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
    where
        S: Serializer,
    {
        let mut me = serializer.serialize_struct("OptionalConfig", 17)?;
        if !self.config_directory.is_none() {
            me.serialize_field("config_directory", &self.config_directory)?;
        }
        if !self.run_directory.is_none() {
            me.serialize_field("run_directory", &self.run_directory)?;
        }
        if !self.cache_directory.is_none() {
            me.serialize_field("cache_directory", &self.cache_directory)?;
        }
        ...
        me.end()
    }
}
lesurp commented

Hey, I'll look into this whenever I have some time, thanks for the feedback :)

ttytm commented

@bryanlarsen could you elaborate on the end result you would like to see from what you are serializing. There is probably a relatively simple way already to achieve what you need.

Edit:
Alternatively, there is a fork, implementing such features. Tho it has well aged dependencies.
https://github.com/revoltchat/OptionalStruct

The idea is that a no-effect version of the optional struct should serialize as {} rather than {"foo": None}

Thanks for pointing me at the fork, some of the other features there are also useful.

I tried switching to the fork you pointed me at. I'd like to use their opt_skip_serializing_none and opt_some_priority options. But their fork has other issues you fixed in 0.3.

opt_skip_serializing_none should be trivial to implement, I'll get around to doing this soon hopefully.

Besides this, the above fork does not seem to do much more that mine, especially compared to the v0.4 I just publishehd.
According to the readme of the fork, here are the other keys differences:

  • Allows docstrings for struct values.

I thought the comments should be included as well in the generated code, but I need to double check.

  • Allow setting #[opt_lenient] to allow other attributes on a struct, e.g. #[model] from wither.

I think this always worked? But fair enough

  • Allow setting #[opt_skip_serializing_none] to add #[serde(skip_serializing_if = "Option::is_none")] to all fields.

TODO, as mentioned

  • Allow setting #[opt_some_priority] make existing Option values take presence over None values in the optional struct.

The recent refactoring in v0.4 change my version's behavior to this.

  • Allow setting #[opt_passthrough] on individual struct fields to include the next attribute on the field in the optional struct as well.

This, too, should already work. But I can take a look for sure.

I don't see much point in the author's fork. Although he has been more active recently, I must give them that.

implemented in v0.4.1