Serde 使用公共字段在内部标记枚举

Tim*_*mmm 3 variant rust serde

我的 JSON 大致如下:

[
  {
     "commonA": 1,
     "commonB": 2,
     "type": "Foo",
     "fooSpecificA": 3,
     "fooSpecificB": 4
  },
  {
     "commonA": 5,
     "commonB": 6,
     "type": "Bar",
     "barSpecificA": 7,
     "barSpecificB": 8
  },
  ...
Run Code Online (Sandbox Code Playgroud)

换句话说,我在内部标记了对象,但有些字段对每种类型都是通用的。我想将它反序列化为这样的:

[
  {
     "commonA": 1,
     "commonB": 2,
     "type": "Foo",
     "fooSpecificA": 3,
     "fooSpecificB": 4
  },
  {
     "commonA": 5,
     "commonB": 6,
     "type": "Bar",
     "barSpecificA": 7,
     "barSpecificB": 8
  },
  ...
Run Code Online (Sandbox Code Playgroud)

塞尔德有可能吗?

E_n*_*ate 9

内部标记的联合struct flattening 结合起来

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Entry {
    #[serde(rename = "commonA")]
    common_a: i64,
    #[serde(rename = "commonB")]
    common_b: i64,
    #[serde(flatten)]
    variant: EntryVariant,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
enum EntryVariant {
    Foo(FooSpecific),
    Bar(BarSpecific),
}

#[derive(Debug, Serialize, Deserialize)]
struct FooSpecific {
    #[serde(rename = "fooSpecificA")]
    foo_specific_a: i64,
    #[serde(rename = "fooSpecificB")]
    foo_specific_b: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct BarSpecific {
    #[serde(rename = "barSpecificA")]
    bar_specific_a: i64,
    #[serde(rename = "barSpecificB")]
    bar_specific_b: i64,
}
Run Code Online (Sandbox Code Playgroud)

操场