serde
serde copied to clipboard
skip serializing when human readable attribute
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).
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.
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"
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).
Yes, you're correct of course, not sure why I suggested this, just serializing what is there makes sense :)
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.
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.
If "being format-agnostic" refers to reusing data structures across different data formats, that hasn't been a goal.
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?