Я бы реализовал это, используя структуру-обертку, которую можно использовать непосредственно для сброса верхнего уровня вложенности, а также через атрибут #[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, см. Можно ли сгладить поля подобъекта при синтаксическом анализе с serde_json?