gpt4 book ai didi

rust - 使用 Serde 反序列化对象时,有没有办法省略包装器/根对象?

转载 作者:行者123 更新时间:2023-11-29 08:13:38 24 4
gpt4 key购买 nike

我有以下对象:

{
"data": {
"id": 1,
"name": "South America",
"countries": {
"data": [
{
"id": 122,
"name": "Brazil",
"capital": "Brasilia"
}
]
}
}
}

我想定义两个结构,ContinentCountry , 省略 data不增加值(value)的包装。

最佳答案

我会使用一个包装器结构来实现这个,它可以直接用于删除嵌套的顶层,也可以通过 #[serde(with = "...")] 属性来实现消除反序列化数据结构中的嵌套级别。


use serde::{Deserialize, Deserializer};

#[derive(Deserialize, Debug)]
struct Continent {
id: u64,
name: String,
#[serde(with = "Wrapper")]
countries: Vec<Country>,
}

#[derive(Deserialize, Debug)]
struct Country {
id: u64,
name: String,
capital: String,
}

#[derive(Deserialize)]
struct Wrapper<T> {
data: T,
}

impl<T> Wrapper<T> {
fn deserialize<'de, D>(deserializer: D) -> Result<T, D::Error>
where
T: Deserialize<'de>,
D: Deserializer<'de>,
{
let wrapper = <Self as Deserialize>::deserialize(deserializer)?;
Ok(wrapper.data)
}
}

fn main() -> serde_json::Result<()> {
let j = r#"
{
"data": {
"id": 1,
"name": "South America",
"countries": {
"data": [
{
"id": 122,
"name": "Brazil",
"capital": "Brasilia"
}
]
}
}
}"#;

let wrapper: Wrapper<Continent> = serde_json::from_str(j)?;
println!("{:#?}", wrapper.data);

Ok(())
}

微不足道的嵌套出现在三个实质上不同的地方:

  1. 与其他领域相邻
  2. 自己在顶层
  3. 本身低于顶层

这三者都需要不同的方法。 #2 和 #3 在这个问题中被观察到。

要解决 #1,请参阅 Is it possible to flatten sub-object fields while parsing with serde_json?

关于rust - 使用 Serde 反序列化对象时,有没有办法省略包装器/根对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54657873/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com