serde icon indicating copy to clipboard operation
serde copied to clipboard

skip serializing when human readable attribute

Open m4b opened this issue 3 years ago • 4 comments
trafficstars

In process of stumbling on skip not working with e.g., bincode (ex: https://docs.rs/bincode/2.0.0-alpha.1/bincode/serde/index.html#known-issues) (which makes sense, given that format), it occurred to me after a suggestion by kvark for a "skip if human readable", and ralith about manual implementations using the is_human_readable method, that my usecase for using skip_serializing_if is actually more precisely, "skip serializing when the format is human readable".

Hence I propose tentatively an additional derive annotation:

    #[serde(skip_serializing_human_readable_if = "Vec::is_empty")]
    pub foos: Vec<Foo>,

Which would skip this field when the format is human readable, e.g., ron, json, but for something like bincode, it would serialize the empty vector (and would then allow deserialization to work correctly).

m4b avatar Mar 19 '22 22:03 m4b

It's worth note that "is human readable" isn't quite the same thing as "is a format which can skip fields", but it's reasonably close. An alternative solution would be to add a fn can_skip_fields() -> bool method or similar to Serializer, default-impl it to true for backwards-compat, and adjust skip_serializing_if to respect it.

Ralith avatar Mar 20 '22 02:03 Ralith

Haven't thought deeply about this suggestion, but this might also potentially fix what seems to be rather serious issue that, e.g., I can add some annotations to a serde struct, serialize it without error, but the result is an object which cannot be deserialized back. (i.e., in a very real sense, it silently fails at the serialization point, instead of deserialization point, which can surface much later, temporally (which is what happened to me))

Ideally, such an implementation that cannot not serialize fields in these cases, e.g., bincode, could error out in the serialization phase, or even better, serialize a default value if possible; although we are back in territory of some kind of annotation like "serialize this only if you have to", which as you say, is stronger/more accurate than "serialize this if not human readable"

m4b avatar Mar 20 '22 03:03 m4b

serialize a default value if possible

I think serializing the actual value when skipping is unsupported would be much less surprising (and avoid imposing a Default constraint).

Ralith avatar Mar 20 '22 17:03 Ralith

Yes, you're correct of course, not sure why I suggested this, just serializing what is there makes sense :)

m4b avatar Mar 20 '22 21:03 m4b

I would prefer not to build something for this into serde_derive. In general it isn't a goal for serde_derive to support complex data structures that need different serialization behavior across different formats.

dtolnay avatar Jul 09 '23 06:07 dtolnay

The status quo is that serde_derive structures which use skip_serializing_if will silently corrupt data under formats like bincode, so I'm not sure a goal of being format-agnostic is being met.

Ralith avatar Jul 09 '23 21:07 Ralith

If "being format-agnostic" refers to reusing data structures across different data formats, that hasn't been a goal.

dtolnay avatar Jul 09 '23 22:07 dtolnay

I'm surprised to hear that. In my circles that's widely understood to be an express goal of serde! Perhaps it merits more prominent documentation as a non-goal?

Ralith avatar Jul 09 '23 22:07 Ralith