2 个版本
0.1.1 | 2024 年 8 月 5 日 |
---|---|
0.1.0 | 2024 年 7 月 22 日 |
#658 在 解析器实现
每月 242 次下载
50KB
1K SLoC
serde-ignored-fields
反序列化和重新序列化类型时保留忽略的字段。
有时你可能希望保留你正在反序列化的东西的忽略字段。如果你控制这个类型,你可以使用 #[serde(flatten)]
属性
#
#[derive(serde::Deserialize, serde::Serialize)]
struct Thing {
name: String,
#[serde(flatten)]
extra_fields: serde_yaml::Mapping,
}
#
#
如果你不控制类型,这个包可以帮到你。你可以用 PreserveIgnoredFields
来包裹类型
use serde_ignored_fields::PreserveIgnoredFields;
#[derive(serde::Deserialize, serde::Serialize)]
struct Thing {
name: String,
}
let thing: PreserveIgnoredFields<Thing, serde_yaml::Mapping> = serde_yaml::from_str("
name: Turbo Encabulator
base_plate:
prefabulated: true
material: aluminite
casing: malleable logarithmic
")?;
assert!(thing.value.name == "Turbo Encabulator");
assert!(thing.ignored_fields["base_plate"]["prefabulated"] == true);
assert!(thing.ignored_fields["base_plate"]["material"] == "aluminite");
assert!(thing.ignored_fields["casing"] == "malleable logarithmic");
如果你启用了 schemars
功能, [PreserveIgnoredFields<T, U>
] 实现 schemars::JsonSchema
特性。它直接转发到 T
的 schemars::JsonSchema
实现。
限制
由于 serde
没有提供对捕获忽略字段的优先级支持,因此存在一些限制。
自描述格式
首先,PreserveIgnoredFields
只与自描述格式(如 JSON、YAML 或 TOML)一起使用。这不足为奇,在实践中也不会是一个真正的限制(如果数据格式没有告诉你字段是什么,你怎么能忽略字段呢?)。
在 serde
术语中:必须支持 serde::Deserializer
的 serde::Deserializer::deserialize_any()
。
序列化/反序列化实现
其次,正在(反)序列化的类型 T
必须表示为键/值映射,并且必须调用 serde::Deserializer::deserialize_ignored_any()
来反序列化被忽略的字段。当遇到未知字段时,它不能产生错误(因此,类型不应使用 #[serde)deny_unknown_fields]
)。
特别是,这意味着它不适用于 外部 标记的枚举、内部 标记的枚举和 无标记 枚举。外部标记的枚举并不总是作为键/值映射序列化(序列化格式控制它们的布局)。内部和无标记的枚举必须查看字段才能知道哪些字段实际上会被忽略。这个crate 确实 与相邻标记的枚举一起工作。
这也意味着它不适用于首先将值反序列化到类似 serde_json::Value
的类型,然后再进一步处理该值。在反序列化时,serde_json::Value
使用所有字段。下一个处理步骤可能再次丢弃它们,但 PreserveIgnoredFields
无法了解这一点。
总之:使用 PreserveIgnoredFields
与使用 serde
的标准 derive 宏的结构体一起工作,只要您没有使用 #[serde)deny_unknown_fields]
。与使用标准 derive 宏的枚举一起使用时,只有在它们是 相邻标记的(它们有 serde tag = "..."
并且 content = "..."
属性)时才会生效。
依赖项
~0.1–9.5MB
~100K SLoC