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
看起来好像您正在尝试手动区分 Foo
和 Bar
。
然而,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
是否可以使用 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
看起来好像您正在尝试手动区分 Foo
和 Bar
。
然而,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