4个版本
0.1.3 | 2023年2月27日 |
---|---|
0.1.2 | 2023年2月23日 |
0.1.1 | 2023年2月23日 |
0.1.0 | 2023年2月22日 |
422 在 无标准库
每月 832 次下载
在 2 个crates中使用了(通过 pagefind)
10KB
rust-patch
使用其他结构体修补结构体
rust-patch
允许您在实现Rust结构体的部分更新时避免样板代码。
只需定义一个包含您字段子集的修补结构体,派生 Patch
特性,并使用 #[patch]
属性指定原始结构体。
修补结构体的字段可以是与原始结构体相同的类型 T
,或者是 Option<T>
。
在后一种情况下,如果修补中对应的字段是 None
,则将被修补的字段将保持不变。
此crate与 no_std
兼容。
容器属性
#[修补 = "..."]
设置要修补的目标结构体
use rust_patch::Patch;
struct Item { data: u32 }
#[derive(Patch)]
#[patch = "Item"]
struct ItemPatch { data: Option<u32> }
字段属性
默认情况下,任何类型为 Option<T>
的修补字段都将按原样应用
if let Some(val) = patch.field {
target.field = val;
}
可以通过以下字段属性更改此行为。
#[修补(as_option)]
as_option
属性允许修补具有以下逻辑的结构体,其中字段本身已经是 Option<T>
if patch.field.is_some() {
target.field = patch.field;
}
如果将此属性应用于没有 is_some()
方法的类型,则会引发错误。
#[修补(direct)]
direct
属性使得字段被像任何其他 T
一样处理,这意味着它将按以下方式应用
target.field = patch.field;
如果将此属性应用于不是 Option<T>
的类型,则为空操作。
示例
use rust_patch::Patch;
use serde::Deserialize;
#[derive(PartialEq, Debug)]
struct User {
id: String,
name: String,
email: String,
}
#[derive(Deserialize, Patch)]
#[patch = "User"]
struct UserPatch {
name: Option<String>,
email: Option<String>,
}
let user = User {
id: "6bf25b70-bffa-49e0-905b-2d2e608e3abd".to_string(),
name: "Max Mustermann".to_string(),
email: "[email protected]".to_string(),
};
let raw_patch = r#"{
"id": "some invalid id",
"email": "[email protected]"
}"#;
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 unchanged
assert_eq! {
patched_user,
User {
id: "6bf25b70-bffa-49e0-905b-2d2e608e3abd".to_string(),
name: "Max Mustermann".to_string(),
email: "[email protected]".to_string()
}
};
依赖
~1.5MB
~36K SLoC