Provides a configurable derive macro that generates another struct with the same fields, but wrapped in
Option<T>
, and implementsPartial
to allow conditionally applying the generated struct fields to the base struct fields.
partially
provides the Partial
trait, which allows applying another structs values to self
, with the intent that the other struct mirrors the fields of self
, but wrapped in Option<T>
.
Further, partially_derive
(or partially
with the derive
feature enabled) supports automatically generating a mirrored struct with each field wrapped in Option<T>
, and generates a Partial
implementation that allows applying the Some
fields of the mirrored struct to the base struct. I expect most folks will be most interested in using the derive macro.
With derive:
``rust
//
partiallyinstalled with feature
derive`
use partially::Partial;
// define a base structure, with the Partial
derive macro
// further, instruct the macro to derive Default
on the generated structure
struct Data {
// since no field options are specified, this field will be mapped
// to an Option<String>
in the generated structure
value: String,
}
// example usage
fn main() {
// since we derived default for the generated struct, we can use that
// to obtain a partial struct filled with None
.
let empty_partial = PartialData::default();
// we can, of course, also specify values ourself
let full_partial = PartialData {
value: Some("modified".to_string()),
};
// define a "base" that we'll operate against
let mut full = Data {
value: "initial".to_string(),
};
// apply the empty partial
full.apply_some(empty_partial);
// note that applying the empty partial had no effect
assert_eq!(full.value, "initial".to_string());
// apply the full partial
full.apply_some(full_partial);
// note that applying the full partial modified the value
assert_eq!(full.value, "modified".to_string());
} ```
Without derive:
```rust use partially::Partial;
struct Base { value: String, }
struct PartialBase {
value: Option
impl partially::Partial for Base { type Item = PartialBase;
#[allow(clippy::useless_conversion)]
fn apply_some(&mut self, partial: Self::Item) {
if let Some(value) = partial.value {
self.value = value.into();
}
}
}
fn main() { let emptypartial = PartialBase::default(); let fullpartial = PartialBase { value: Some("modified".to_string()), };
let mut data = Base {
value: "initial".to_string(),
};
data.apply_some(empty_partial);
assert_eq!(data.value, "initial".to_string());
data.apply_some(full_partial);
assert_eq!(data.value, "modified".to_string())
}
```
Usage example:
#[partially(derive(Debug, Default))]
.
Instructs the macro to generate a #[derive(...)]
attribute on the generated struct.
Usage example:
#[partially(rename = "MyGeneratedStruct")]
.
Instructs the macro to use a given identifier for the generated struct. By default, PartialBaseStructName
is used, where BaseStructName
is the name of the original struct.
Usage example:
#[partially(crate = "my_partially_crate")]
.
Instructs the macro to use a different base path for the Partial
trait implementation. By default, partially
is used. This can be useful if you've forked the partially
crate.
Usage example:
#[partially(rename = "new_field_name")]
.
Instructs the macro to use a given identifier for the generated field. By default, the same name as the base struct is used.
Usage example:
#[partially(omit)]
.
Instructs the macro to omit the field from the generated struct. By default, no fields are omitted.
Usage example:
#[partially(transparent)]
.
Instructs the macro to skip wrapping the generated field in Option<T>
, instead transparently mirroring the field type into the generated struct.
Usage example:
#[partially(as_type = "Option<f32>")]
.
Instructs the macro to use the provided type instead of Option<T>
when generating the field. Note that the provided type will be used verbatim, so if you expect an Option<T>
value, you'll need to manually specify that.
Note: When using as_type
, the given type must Into<BaseType>
where BaseType
is the original field type. This is required for Partial
trait implementation.