#[derive(From)]: allow specifying default values for struct/enum variant fields
Resolves https://github.com/JelteF/derive_more/issues/149
Synopsis
When deriving From, it is often useful to let some fields be a certain
"constant" default value instead of being part of the source tuple type.
The most obvious such value is Default::default(), but specifying
other values is very useful as well.
This is my first time touching proc-macros, please handle with care :)
The tests pass though (except for one that was broken before my changes), and this change shouldn't break anything.
I'm also open to alternative designs (e.g. #[from(default = <...>)] instead of #[from(...)])
Solution
Add handling of #[from] and #[from(<default value>)] attrs
on struct (and enum struct) fields. For more information about the
handling details, please consult the included documentation changes
and/or tests.
Excerpt from documentation
If you add a #[from(<default value>)] attribute to any fields of the struct,
then those fields will be omitted from the tuple and be set to the default value
in the implementation:
# use std::collections::HashMap;
#
# use derive_more::From;
#
#[derive(Debug, From, PartialEq)]
struct MyWrapper {
inner: u8,
#[from(1)]
not_important: u32,
#[from(HashMap::new())]
extra_properties: HashMap<String, String>,
}
assert_eq!(MyWrapper { inner: 123, not_important: 1, extra_properties: HashMap::new(), }, 123.into());
If you add a #[from] value to any fields of the struct, then only those
fields will be present in the tuple and the rest will be either set to
Default::default() or taken from their default values specified in
#[from(<default value>)]:
# use std::collections::HashMap;
#
# use derive_more::From;
#
#[derive(Debug, From, PartialEq)]
struct Location {
#[from]
lat: f32,
#[from]
lon: f32,
#[from(String::from("Check out my location!"))]
description: String,
extra_properties: HashMap<String, String>,
}
// This is equivalent to:
// #[derive(Debug, From, PartialEq)]
// struct Location {
// lat: f32,
// lon: f32,
// #[from(String::from("Check out my location!"))]
// description: String,
// #[from(Default::default())]
// extra_properties: HashMap<String, String>,
// }
assert_eq!(
Location {
lat: 41.7310,
lon: 44.8067,
description: String::from("Check out my location!"),
extra_properties: Default::default(),
},
(41.7310, 44.8067).into()
);
Checklist
- [x] Documentation is updated (if required)
- [x] Tests are added/updated (if required)
- [x] CHANGELOG entry is added (if required)