I have a struct that has 20 fields:
struct StructA {
value1: i32,
value2: i32,
// ...
value19: i32,
day: chrono::NaiveDate,
}
I'd like to impl Default
trait for StructA
. I tried to add #[derive(Default)]
to the struct, but chrono::NaiveDate
doesn't implement Default
.
I then tried to implement Default
for StructA
:
impl Default for StructA {
fn default() -> Self {
Self {
value1: Default::default(),
value2: Default::default(),
// ...
value19: Default::default(),
day: chrono::NaiveDate::from_ymd(2021, 1, 1),
}
}
}
This code works fine, but the parts of value1
through value19
are redundant. Is there a solution with less code?
StructA
to deserialize JSON data via serde-json so I can't change the struct's definition.day: chrono::NaiveDate
is always given from JSON data, so I want to avoid day: Option<chrono::NaiveDate>
.The derivative crate makes this kind of thing a breeze:
#[derive(Derivative)]
#[derivative(Default)]
struct StructA {
value1: i32,
value2: i32,
// ...
value19: i32,
#[derivative(Default(value = "NaiveDate::from_ymd(2021, 1, 1)"))]
day: NaiveDate,
}
If you want to avoid external crates, your options are:
Default::default()
for each numeric field, a simple 0
will work as well.day
an Option
and derive Default
, with the downside that it will default to None
, bear a size penalty, and you'll have to use unwrap_or(0)
at run-time to access it.day
a newtype that wraps NaiveDate
and implements Default
to set it to the desired value, with the downside that you'll need to access the underlying NaiveDate
through a (zero-cost) field or method.