rust - 有没有办法使用 Rust 的 serde / serde_json 来“修补”一个结构?
问题描述
是否有一种相当简单的方法可以使用 serde/serde_json 来获取现有结构并仅更新 JSON 中存在的那些字段?这基本上相当于在运行时而不是在编译时通过实现 Default trait 或默认值生成器函数来设置默认值。
当您有一个 RESTful API 时,这似乎是一个非常常见的用例,您希望在其中提交更新到状态,只修改指定的字段并保持未指定的字段不变。
我可以通过反序列化为动态值类型,然后进行大匹配或 if/else 块来更新字段来做到这一点,但这既冗长又丑陋。我想知道 serde 是否有什么可以处理的。
解决方案
Serde 不支持这样的东西。如果我需要这样做,我可能会创建一个并行结构,其中所有字段都是可选的:
use serde::Deserialize;
#[derive(Deserialize)]
pub struct MyData {
foo: String,
bar: u64,
wibble: bool,
}
#[derive(Deserialize)]
pub struct MyDataPatch {
foo: Option<String>,
bar: Option<u64>,
wibble: Option<bool>,
}
impl MyData {
pub fn patch(&mut self, update: MyDataPatch) {
if let Some(foo) = update.foo {
self.foo = foo;
}
if let Some(bar) = update.bar {
self.bar = bar;
}
if let Some(wibble) = update.wibble {
self.wibble = wibble;
}
}
}
这是更多的代码重复,但运行时开销更少。
如果我有很多这些,那么我会用宏生成所有这些,而不是手动编写。您可以使用可派生的特征来做到这一点,例如:
trait Patch {
type Patch; // Self with all optional fields
fn patch(&mut self, patch: &Self::Patch);
}
推荐阅读
- c++ - 什么是 char (*var)[6] 和 char* var[6]?
- android - Flutter 无法从资产文件夹中检测到“model.tflite”文件(FileNotFoundException)
- database - Kubernetes 上的 etcd 数据库集群行为不端
- c# - 有没有办法重定向到新页面是 System.NullReferenceException 被触发?
- php - 将额外模型附加到 BelongstoMany 关系
- javascript - javascript d3 timeParse utcParse
- c# - 调试从 C++ 调用的 C# dll(嵌入 Mono)
- ruby - logstash - 用换行符分割消息
- asp.net-core - Asp.Net Core 3.1 模型绑定不起作用
- java - 如何隐藏某些内容以不显示给 recyclerview