I use Serde to deserialize a custom configuration file written in yaml. The file can contain definitions of various kinds that I represent as intentally tagged enums, like this:
OfKindFoo:
kind: Foo
bar: bar;
baz: baz;
OfKindQux:
kind: Qux
quux: qux;
In Rust, I represent it like this:
#[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
}
I want the app user to be able to omit the "kind" field completely, and when it is omitted Serde defaults to deserializing as Foo.
I started to implement custom Deserialize
on Definition, I'm trying to deserialize it as map and manually look for "kind" key and return a respective enum variant based on this key and whether it is present. But I need to somehow "forward" deserialization of other map fields to Foo::deserialize
or Bar::deserialize
, respectively. fn deserialize
only takes one argument which is Deserializer
. Is there a way to "convert" map into a deserializer or somehow else get a deserializer that "starts" on that particular map? Performance is a non issue.