I checked and didn't find a topic on this. However, there are quite many, so maybe I overlooked it. Sorry in that case.
Having worked with serialization again today, I recognized two patterns that I believe could be simpler out of the box.
A trait for is_empty and a trait for is_default. I believe this should be two dedicated traits.
Empty
For the lack of a better name I use Empty, and the idea is like this:
pub trait Empty {
fn is_empty(&self) -> bool;
}
That would map nicely to things that can be turned into iterators, like: Vec, HashMap, but also Option.
And instead of having a bunch of different serde attributes like #[serde(skip_serializing_if="HashMap::is_empty")] it would allow for a simpler approach of #[serde(skip_serializing_if="Empty::is_empty")] for all cases. Or maybe even: #[serde(skip_serializing_empty)], expected the type to implement Empty.
It might also be possible to come up with a derive, which does that automatically for e.g. structs:
#[derive(Empty)]
struct MyData {
data1: Option<Data1>,
data2: Option<Data2>,
}
IsDefault
The other pattern is a check if the value is equal to the "default value". Meaning that: (value == Default::default()) == true. Which could be implemented as:
pub trait IsDefault {
fn is_default(&self) -> bool;
}
With implementations like this:
impl <T> IsDefault for Option<T> {
fn is_default(&self) -> bool {
self.is_none()
}
}
Having available would also make it easier to define serialization: #[serde(default, skip_serializing_if="IsDefault::is_default")]. Or maybe just: #[serde(default, skip_serializing_default)].
Having this as part of the Default trait doesn't seem to work, as that would require all Default implementations to also require at least PartialEq.
Alternatives
An alternative to adding this to std or core would be to have a dedicated crate for this. However, it feels like a very basic feature, and having Rust support for this out of the box, would make adoption of this in crates like serde more likely.