【问题标题】:Rust deserialize json based on an enum in the jsonRust 基于 json 中的枚举反序列化 json
【发布时间】:2020-02-27 21:51:54
【问题描述】:

是否可以使用 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 字段确定data 中存在哪种类型的结构数据。例如,给定以下伪代码,我希望最终拥有一个 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 的类型以启用此功能。

【问题讨论】:

    标签: json struct rust serde


    【解决方案1】:

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

    【讨论】:

    • 啊,谢谢,这很有帮助。我不知道enum AllMyStuff { Foo(Foo), Bar(Bar) } 是可能的,知道这一点非常有见地。您对serde_json::Value 的使用最终是我想要去的路线,并将我带到我需要的地方。谢谢!
    【解决方案2】:

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

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

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

    点击here查看它的实际效果。

    【讨论】:

      猜你喜欢
      • 2023-02-22
      • 2013-09-01
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2013-09-04
      • 1970-01-01
      相关资源
      最近更新 更多