Patch structs with other structs
rust-patch
allows you to avoid boilerplate code when implementing partial updates of Rust structs.
Simply define a patch struct containing a subset of your fields, derive the Patch
trait,
and specify the original struct using the #[patch]
attribute.
Fields of a patch struct may either be of the same type T
as in the original struct or Option<T>
.
In the latter case, the field to be patched will be left unchanged if the corresponding field in the patch is None
This crate is no_std
compatible.
#[patch = "..."]
Set target struct to be patched ```rust use rust_patch::Patch; struct Item { data: u32 }
struct ItemPatch { data: Option
#[patch(direct)]
By default, any fields in the patch of type Option<T>
will be applied as such:
rust ignore
if let Some(val) = patch.field {
target.field = val;
}
In some cases, e.g. when the field in the target struct is also an Option
, this behavior is undesirable.
The direct
attribute makes it so that the field is treated like any other T
, meaning it will be applied like this:
rust ignore
target.field = patch.field;
#[patch(as_option)]
This attribute also primarily changes the handling of Option
types.
Unlike with direct
however, the original value will not be overwritten if the patch value is None
.
rust ignore
if patch.field.is_some() {
target.field = patch.field;
}
```rust use rust_patch::Patch; use serde::Deserialize;
struct User { id: String, display_name: String, email: String, }
struct UserPatch {
display_name: Option
let user = User { id: "6bf25b70-bffa-49e0-905b-2d2e608e3abd".tostring(), displayname: "Max Mustermann".tostring(), email: "max.mustermann@example.org".tostring(), };
let raw_patch = r#"{ "id": "some invalid id", "email": "max.mustermann@example.com" }"#;
let patch: UserPatch = serdejson::fromstr(rawpatch).unwrap(); let patcheduser = patch.apply(user);
// Since id
is not part of our UserPatch
struct it stays unchanged
asserteq! {
patcheduser,
User {
id: "6bf25b70-bffa-49e0-905b-2d2e608e3abd".tostring(),
displayname: "Max Mustermann".tostring(),
email: "max.mustermann@example.com".tostring()
}
};
```