【发布时间】:2020-07-27 17:08:15
【问题描述】:
我使用 Serde 反序列化用 YAML 编写的自定义配置文件。该文件可以包含我表示为内部标记枚举的各种定义:
OfKindFoo:
kind: Foo
bar: bar;
baz: baz;
OfKindQux:
kind: Qux
quux: qux;
我在 Rust 中这样表示它:
#[derive(Deserialize)]
#[serde(tag = "kind")]
enum Definition {
Foo(Foo),
Qux(Qux),
}
#[derive(Deserialize)]
struct Foo {
bar: String,
baz: String,
}
#[derive(Deserialize)]
struct Qux {
quux: String,
}
我希望用户能够完全省略 kind 字段,当省略时,Serde 应该默认将其反序列化为 Foo。
我开始在Definition 上实现Deserialize。我正在尝试将其反序列化为映射并查找 kind 键并根据此键及其是否存在返回相应的枚举变体。
我需要以某种方式将其他映射字段的反序列化分别“转发”到Foo::deserialize 或Bar::deserialize。 fn deserialize 只接受一个参数,即Deserializer。有没有办法将地图“转换”为反序列化器或以其他方式获得在该特定地图上“启动”的反序列化器?
我不能使用#[serde(other)],因为它会为缺少的标签返回Err。即使没有,文档指出other 只能应用于“单元变体”,即不包含任何数据的变体。
【问题讨论】: