4

我正在编写一个 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,
}

Dictionary如何使用 Serde将我的 JSON 数据(反)序列化到/从序列化?

4

1 回答 1

9

您的代码中有逻辑错误。JSON 文件中的结构描述了一个关联数组,但您Dictionary不支持多个键值对。正如Stargateur 在评论中所说,您可以使用HashMapas SerdehasSerializeDeserializeimplementations for 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) 属性添加到Dictionary

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

如果HashMap或任何BTreeMapstd符合您的需求,您也可以Dictionary自己实施。有关更多详细信息,请参阅此处此处的文档。

于 2018-04-08T15:24:44.533 回答