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.