Я использую 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
.
. Я начал внедрять Deserialize
в Definition
. Я пытаюсь десериализовать его как карту и найти ключ kind
и вернуть соответствующий вариант enum на основе этого ключа и его наличия.
Мне нужно как-то "переслать" десериализацию других полей карты на Foo::deserialize
или Bar::deserialize
, соответственно. fn deserialize
принимает только один аргумент Deserializer
. Есть ли способ «преобразовать» карту в десериализатор или иным образом получить десериализатор, который «запускается» на этой конкретной карте?
Я не могу использовать #[serde(other)]
, потому что он возвращает Err
за отсутствующий тег. Даже если это не так, в документации говорится, что other
может применяться только к «варианту устройства», варианту, не содержащему никаких данных.