如何在 Serde 中(反)序列化强类型 JSON 字典?

How to (de)serialize a strongly typed JSON dictionary in Serde?

我正在编写一个 Rust 应用程序,它处理来自带有 public 接口的 TypeScript 客户端的 JSON 消息。我已经使用 serde_derive 编写了一些代码并且运行良好,但我不知道如何实现字典;例如:

{
  "foo" : { "data" : 42 },
  "bar" : { "data" : 1337 }
}

这里的键是字符串 "foo""bar",字典的值遵循以下模式:

use serde_derive;
use serde_json::Number;

#[derive(Serialize, Deserialize)]
struct DictionaryValue {
    data: Number,
}

我希望以这种方式访问​​ JSON 数据:

#[derive(Serialize, Deserialize)]
struct Dictionary {
    key: String,
    value: DictionaryValue,
}

如何使用 Serde(反)序列化我的 JSON 数据 into/from Dictionary

您的代码存在逻辑错误。您的 JSON 文件中的结构描述了一个关联数组,但您的 Dictionary 不支持多个 key-value-pairs。作为 , you may use HashMap as Serde has Serialize and Deserialize implementations for HashMap.

您可以将 Dictionary 重写为

,而不是使用单个 key-value-pair
type Dictionary = HashMap<String, DictionaryValue>;

您可以通过

检索数据
let dict: Dictionary = serde_json::from_str(json_string).unwrap();

如果您现在想将所有内容包装在 Dictionary 结构中,它将如下所示:

#[derive(Serialize, Deserialize)]
struct Dictionary {
    inner: HashMap<String, DictionaryValue>,
}

问题是,serde_json 现在需要

{
  "inner": {
    "foo" : { "data" : 42 },
    "bar" : { "data" : 1337 }
  }
}

要摆脱这种情况,您可以将 serde(flatten) attribute 添加到 Dictionary:

#[derive(Serialize, Deserialize, Debug)]
struct Dictionary {
    #[serde(flatten)]
    inner: HashMap<String, DictionaryValue>,
}

如果HashMap or any BTreeMap from std does not fit your needs, you can also implement your Dictionary on your own. See the docs here and here了解更多详情。