如何在Serde中对强类型JSON字典进行序列化和反序列化?

5

我正在编写一个Rust应用程序,处理来自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 数据序列化/反序列化成/自 Dictionary

你必须使用一个hashmap - Stargateur
1
@Stargateur 不是的,任何关联容器都可以使用,比如 BTreeMap。你甚至可以自己实现一个。请参阅文档 这里这里 - Tim Diekmann
1个回答

10

您的代码存在逻辑错误。您的JSON文件中的结构描述了一个关联数组,但是您的Dictionary不支持多个键值对。如Stargateur在评论中所述,您可以使用HashMap,因为SerdeHashMap实现了SerializeDeserialize

您可以将Dictionary重写为多个键值对的形式,而非单一键值对。

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

为了解决这个问题,您可以在Dictionary中添加serde(flatten)属性
#[derive(Serialize, Deserialize, Debug)]
struct Dictionary {
    #[serde(flatten)]
    inner: HashMap<String, DictionaryValue>,
}

如果HashMapstd中的任何BTreeMap都不符合您的需求,您也可以自己实现Dictionary。有关更多详细信息,请参见此处here和此处here的文档。

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