Rust 根据 json 中的枚举反序列化 json

Rust deserialize json based on an enum in the json

是否可以使用 JSON 中的值来确定如何使用 serde 反序列化 JSON 的其余部分?例如,考虑以下代码:

use serde::{Serialize, Deserialize};
use serde_repr::*;

#[derive(Serialize_repr, Deserialize_repr, Debug)]
#[repr(u8)]
enum StructType {
    Foo = 1,
    Bar = 2
}

#[derive(Serialize, Deserialize, Debug)]
struct Foo {
    a: String,
    b: u8
}

#[derive(Serialize, Deserialize, Debug)]
struct Bar {
    x: String,
    y: u32,
    z: u16
}

#[derive(Serialize, Deserialize, Debug)]
struct AllMyStuff {
    type: StructType,
    data: //HELP: Not sure what to put here
}

我想要实现的是数据反序列化,即使在多个步骤中,AllMyStuff 中的 type 字段确定 [=] 中存在哪种类型的结构数据16=]。例如,给定以下伪代码,我希望最终得到一个包含正确数据的 Bar 结构:

data = {"type": "2", "data": { "x": "Hello world", "y": "18", "z": "5" } }
// 1) use serde_json to deserialize a AllMyStuff struct, not erroring on the "data" blob
// 2) Now that we know data is of type "2" (or Bar), parse the remaining "data" into a AllMyStuff struct

如果步骤 (1) 和 (2) 能够以某种方式一步完成,那就太棒了,但不是必需的。我不确定要在 AllMyStuff 结构中声明哪种类型的 data 来启用此功能。

我可能遗漏了一些东西,但是 AllMyStuff 看起来好像您正在尝试手动区分 FooBar

然而,Rust 有一个内置方法来做到这一点:

#[derive(Serialize, Deserialize, Debug)]
enum AllMyStuff {
    Foo(Foo),
    Bar(Bar),
}

单击 here 查看实际效果。

您可以使用 serde_json::Value 作为 AllMyStuff::data 的类型。它将反序列化 any 有效的 json 对象并实现 Deserialize 本身,因此一旦反序列化的类型已知(通过 AllMyStuff::type).虽然这需要更多的间歇步骤和(主要是临时的)类型,但它可以让您免于在 enum AllMyStuff { Foo(Foo), Bar(Bar) }.

上手动实施 Deserialize