Skip to content

Repository files navigation

rust-patch

Patch structs with other structs

Build statusCrates.ioDocumentation

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.

Container attributes

#[patch = "..."]

Set target struct to be patched

use rust_patch::Patch;structItem{data:u32}#[derive(Patch)]#[patch = "Item"]structItemPatch{data:Option<u32>}

Field attributes

By default, any fields in the patch of type Option<T> will be applied as such:

ifletSome(val) = patch.field{
target.field = val;}

this behavior can be changed by the following field attributes.

#[patch(as_option)]

The as_option attribute allows patching structs where a field itself is already an Option<T> with the following logic:

if patch.field.is_some(){
target.field = patch.field;}

Applying this attribute to a field with a type without an is_some() method results in an error.

#[patch(direct)]

The direct attribute makes it so that the field is treated like any other T, meaning it will be applied like this:

target.field = patch.field;

Applying this attribute to a field where the type is not Option<T> is a no-op.

Example

use rust_patch::Patch;use serde::Deserialize;#[derive(PartialEq,Debug)]structUser{id:String,name:String,email:String,}#[derive(Deserialize,Patch)]#[patch = "User"]structUserPatch{name:Option<String>,email:Option<String>,}let user = User{id:"6bf25b70-bffa-49e0-905b-2d2e608e3abd".to_string(),name:"Max Mustermann".to_string(),email:"max.mustermann@example.org".to_string(),};let raw_patch = r#"{ "id": "some invalid id", "email": "max.mustermann@example.com"}"#;let patch:UserPatch = serde_json::from_str(raw_patch).unwrap();let patched_user = patch.apply(user);// Since `id` is not part of our `UserPatch` struct it stays unchangedassert_eq!{
patched_user,User{
id:"6bf25b70-bffa-49e0-905b-2d2e608e3abd".to_string(),
name:"Max Mustermann".to_string(),
email:"max.mustermann@example.com".to_string()}};

About

Patch structs with other structs

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages