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

时间:2018-04-08 12:46:33

标签: json rust serde

我正在编写一个Rust应用程序,它使用公共接口处理来自TypeScript客户端的JSON消息。我使用serde_derive编写了一些代码并且运行良好,但我无法弄清楚如何实现字典; e.g:

{
  "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(de)将我的JSON数据序列化为Dictionary /来自{{1}}?

1 个答案:

答案 0 :(得分:5)

您的代码中存在逻辑错误。 JSON文件中的结构描述了一个关联数组,但您的Dictionary不支持多个键值对。作为Stargateur stated in the comments,您可以使用HashMap作为Serde SerializeDeserialize HashMap的实现。

您可以将Dictionary重写为

,而不是使用单个键值对
type Dictionary = HashMap<String, DictionaryValue>;

您可以通过

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

如果您现在想要将所有内容都包装在Dictionary - struct中,它将如下所示:

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

如果HashMapstd中的任何BTreeMap不符合您的需求,您也可以自行实施Dictionary。有关详细信息,请参阅文档herehere