反序列化以空对象为值的地图

Deserialize map with empty objects as values

我有 json 个文档,其中可能包含具有引用空对象的键的对象,就像这样

{
  "mylist": {
    "foo": {},
    "bar": {}
  }
}

我想将它们反序列化为 Vec 字符串(稍后将其序列化回上述格式)

pub struct MyStruct {
  #[serde(skip_serializing_if = "Option::is_none")]
  pub my_list: Option<Vec<String>>; // should contain "foo", "bar"
}

我如何使用 serde 做到这一点?

您需要编写自己的反序列化方法,并使用deserialize_with或直接为您的类型实现:

use serde::Deserialize; // 1.0.127
use serde::Deserializer;
use serde_json;
use std::collections::HashMap; // 1.0.66

#[derive(Deserialize, Debug)]
pub struct MyStruct {
    #[serde(deserialize_with = "deserialize_as_vec", alias = "mylist")]
    pub my_list: Vec<String>,
}

#[derive(Deserialize)]
struct DesHelper {}

fn deserialize_as_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>,
{
    let data: HashMap<String, DesHelper> = HashMap::<String, DesHelper>::deserialize(deserializer)?;
    Ok(data.keys().cloned().collect())
}

fn main() {
    let example = r#"
{
  "mylist": {
    "foo": {},
    "bar": {}
  }
}"#;

    let deserialized: MyStruct = serde_json::from_str(&example).unwrap();
    println!("{:?}", &deserialized);
}

结果:

MyStruct { my_list: ["foo", "bar"] }

Playground

注意它们的空部分使用了辅助结构。代码非常简单,你基本上反序列化一个地图,然后只需要你需要的键。