4 个版本
0.1.3 | 2024年5月6日 |
---|---|
0.1.2 | 2024年4月22日 |
0.1.1 | 2024年4月20日 |
0.1.0 | 2024年4月20日 |
在 编码 中排名第 1091
每月下载量 168
14KB
190 行(不包括注释)
serde-sated(相邻标记枚举反序列化[带未标记变体])
此包提供衍生宏,用于在反序列化相邻标记枚举变体时覆盖 serde::Deserialize 的默认行为,并使用未标记值作为后备。
默认 Deserialize 有什么问题?
看看下面的代码
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "resourceType", content = "resource")]
pub enum ResourceStruct {
Number(u64),
String(String),
Complex(Complex),
#[serde(untagged)]
Unknown(serde_json::Value),
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Complex {
pub a: u64,
pub b: u64,
}
#[test]
fn deserialize_json() {
let missing_field_b_in_complex_variant = json!({
"resourceType": "Complex",
"resource": {
"a": 2000
}
});
let result = serde_json::from_value::<ResourceStruct>(missing_field_b_in_complex_variant).unwrap();
eprintln!("Resource: {:#?}", result);
}
这将打印
Resource: Unknown(
Object {
"resource": Object {
"a": Number(2000),
},
"resourceType": String("Complex"),
},
)
如您所见,Complex 变体中缺少字段 "b" 导致 serde 默认到未标记变体。
解决方案
这可能不是预期的行为 - 此 crate 允许更改此行为,而不是默认到未标记变体,它将返回正确的错误。
让我们将 ResourceStruct derive 属性更改为使用 serde_sated::deserialize_enum_with_untagged_as_fallback
use serde::{Deserialize, Serialize};
use serde_json::json;
use serde_sated::deserialize_enum_with_untagged_as_fallback;
#[derive(Debug, deserialize_enum_with_untagged_as_fallback, Serialize)]
#[serde(tag = "resourceType", content = "resource")]
pub enum ResourceStruct {
Number(u64),
String(String),
Complex(Complex),
#[serde(untagged)]
Unknown(serde_json::Value),
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Complex {
pub a: u64,
pub b: u64,
}
#[test]
fn deserialize_json() {
let missing_field_b_in_complex_variant = json!({
"resourceType": "Complex",
"resource": {
"a": 2000
}
});
let result = serde_json::from_value::<ResourceStruct>(missing_field_b_in_complex_variant);
eprintln!("Resource: {:#?}", result);
}
现在结果将是
Resource: Err(
Error("missing field `b`", line: 0, column: 0),
)
依赖关系
~245–670KB
~16K SLoC