Serde内部标记枚举与共有字段

6
我大致有这样的JSON:
[
  {
     "commonA": 1,
     "commonB": 2,
     "type": "Foo",
     "fooSpecificA": 3,
     "fooSpecificB": 4
  },
  {
     "commonA": 5,
     "commonB": 6,
     "type": "Bar",
     "barSpecificA": 7,
     "barSpecificB": 8
  },
  ...

换句话说,我有内部标记的对象,但是一些字段对于每种类型都是共同的。我想将其反序列化为类似于这样的内容:

struct Entry {
  commonA: i64,
  commonB: i64,
  variant: EntryVariant,
}

enum EntryVariant {
  Foo(FooSpecific),
  Bar(BarSpecific),
}

struct FooSpecific {
  fooSpecificA: i64,
  fooSpecificB: i64,
}

struct BarSpecific {
  barSpecificA: i64,
  barSpecificB: i64,
}

使用Serde可以实现这个吗?


顺便提一下,惯用的 Rust 编程风格中,变量、方法、宏、字段和模块使用 snake_case;类型和枚举变体使用 UpperCamelCase;静态变量和常量使用 SCREAMING_SNAKE_CASE - Shepmaster
是的,我知道,但是大量使用 #[rename_all()] 属性会使示例不够清晰。 - Timmmm
2
你可以重新命名相应的JSON,考虑到你最初是自己创建的。 - Shepmaster
真的。这里也不是很重要! - Timmmm
1个回答

15

内部标记联合体结构展平结合起来。

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,
}

Playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接