没有内置的属性可以实现此功能,但您可以为自己的Object
类型编写Deserialize
实现,将首先反序列化到某些中间辅助表示,然后重新排列数据以获得所需的结构体。
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use serde::{Deserialize, Deserializer};
#[derive(Debug)]
struct Object {
name: String,
count: i32,
foo: String,
}
impl<'de> Deserialize<'de> for Object {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
#[derive(Deserialize)]
struct Outer {
name: String,
info: Inner,
}
#[derive(Deserialize)]
struct Inner {
count: i32,
foo: String,
}
let helper = Outer::deserialize(deserializer)?;
Ok(Object {
name: helper.name,
count: helper.info.count,
foo: helper.info.foo,
})
}
}
fn main() {
let j = r#"{
"name": "myobject",
"info": {
"count": 3,
"foo": "bar"
}
}"#;
println!("{:#?}", serde_json::from_str::<Object>(j).unwrap());
}
输出结果为:
Object {
name: "myobject",
count: 3,
foo: "bar"
}
无关紧要的嵌套出现在三个实质性不同的地方:
- 与其他字段相邻
- 在顶级自身处
- 在顶级以下自身处
这三种情况需要不同的处理方法。#1是在这个问题中观察到的。
要解决#2或#3,请参见如何在使用Serde反序列化对象时省略包装器/根对象?
#[serde(deserialize_with = "path")]
是另一个很好的选择。https://github.com/serde-rs/serde/issues/868 - Manvir