简体   繁体   English

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

[英]Rust deserialize json based on an enum in the json

Is it possible to use a value in JSON to determine how to deserialize the rest of the JSON using serde?是否可以使用 JSON 中的值来确定如何使用 serde 反序列化 JSON 的其余部分? For example, consider the following code:例如,考虑以下代码:

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
}

What I'm trying to achieve is deserialization of the data, even if in multiple steps, where the type field in the AllMyStuff determines which type of struct data is present in data .我想要实现的是数据的反序列化,即使在多个步骤中, AllMyStuff中的type字段确定 data 中存在哪种类型的结构data For example, given the following pseudocode, I'd like to ultimately have a Bar struct with the proper data in it:例如,给定以下伪代码,我希望最终拥有一个包含正确数据的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

If steps (1) and (2) are somehow able to be done in a single step, that would be awesome but not needed.如果步骤 (1) 和 (2) 能够以某种方式在一个步骤中完成,那会很棒但不需要。 I'm not sure what type of type to declare data in the AllMyStuff struct to enable this as well.我不确定在AllMyStuff结构中声明什么类型的data来启用它。

I may be missing something, but AllMyStuff looks as if you are trying to manually distinguish between Foo and Bar .我可能遗漏了一些东西,但AllMyStuff看起来好像您正在尝试手动区分FooBar

However, Rust, has a built-in way of doing this:然而,Rust 有一种内置的方式来做到这一点:

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

Click here to see it in action.单击此处查看它的运行情况。

You can use serde_json::Value as the type for AllMyStuff::data .您可以使用serde_json::Value作为AllMyStuff::data的类型。 It will deserialize any valid json object and also implements Deserialize itself, so it can be further deserialized once the type to deserialize to is known (via AllMyStuff::type ).它将反序列化任何有效的 json 对象并实现Deserialize本身,因此一旦知道要反序列化的类型(通过AllMyStuff::type ),它就可以进一步反序列化。 While this requires more intermittent steps and (mostly temporary) types, it saves you from manually implementing Deserialize on an enum AllMyStuff { Foo(Foo), Bar(Bar) } .虽然这需要更多的间歇步骤和(主要是临时的)类型,但它使您enum AllMyStuff { Foo(Foo), Bar(Bar) }enum AllMyStuff { Foo(Foo), Bar(Bar) }上手动实现Deserialize

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM