反序列化以空对象为值的地图
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"] }
注意它们的空部分使用了辅助结构。代码非常简单,你基本上反序列化一个地图,然后只需要你需要的键。
我有 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"] }
注意它们的空部分使用了辅助结构。代码非常简单,你基本上反序列化一个地图,然后只需要你需要的键。