rust - 有没有办法在使用 Serde 反序列化对象时省略包装器/根对象?
问题描述
我有以下对象:
{
"data": {
"id": 1,
"name": "South America",
"countries": {
"data": [
{
"id": 122,
"name": "Brazil",
"capital": "Brasilia"
}
]
}
}
}
我想定义两个结构,Continent
并且Country
省略data
不增加价值的包装。
解决方案
我将使用一个包装结构来实现这一点,该结构可以直接用于删除顶层嵌套,也可以通过一个#[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(())
}
在三个实质上不同的地方出现了无关紧要的嵌套:
- 与其他领域相邻
- 自己在顶层
- 本身低于顶层
这三个都需要不同的方法。在这个问题中观察到#2 和#3。
要解决 #1,请参阅Is it possible to flatten sub-object fields while parsing with serde_json?
推荐阅读
- html - 父标签样式能否在悬停时优先于子标签的类似样式
- javascript - 如果我知道页数,如何在 AngularJS 中创建页面项?
- xml - 在 nifi 过程中将电子符号转换为数字
- angular - 从 URL 添加图像
- android - 如何为 ui 线程同时创建不同的领域实例?
- react-native - 从 AccessibilityService 访问 react-native 数据
- d3.js - d3.js:增量转换翻译
- javascript - 带有laravel刀片模板循环和总和的javascript
- titanium - appcelerator Titan 中的 Facebook 受众网络
- gigya - 使用 WebSDK 的 Gigya 注册