#fields #serde #ignored #serde-yaml #field

serde-ignored-fields

使用 serde 保留忽略的字段

2 个版本

0.1.1 2024 年 8 月 5 日
0.1.0 2024 年 7 月 22 日

#658解析器实现

Download history 108/week @ 2024-07-20 10/week @ 2024-07-27 117/week @ 2024-08-03 7/week @ 2024-08-10

每月 242 次下载

BSD-2-Clause

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 特性。它直接转发到 Tschemars::JsonSchema 实现。

限制

由于 serde 没有提供对捕获忽略字段的优先级支持,因此存在一些限制。

自描述格式

首先,PreserveIgnoredFields 只与自描述格式(如 JSON、YAML 或 TOML)一起使用。这不足为奇,在实践中也不会是一个真正的限制(如果数据格式没有告诉你字段是什么,你怎么能忽略字段呢?)。

serde 术语中:必须支持 serde::Deserializerserde::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