I have the following object:
{
"data": {
"id": 1,
"name": "South America",
"countries": {
"data": [
{
"id": 122,
"name": "Brazil",
"capital": "Brasilia"
}
]
}
}
}
I'd like to define two structs, Continent
and Country
, omitting the data
wrappings which don't add value.
I would implement this using a wrapper struct that can be used directly for dropping the top level of nesting as well as through a #[serde(with = "...")]
attribute for eliminating levels of nesting within the deserialized data structure.
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(())
}
There are three materially different places where insignificant nesting arises:
All three require different approaches. #2 and #3 are observed in this question.
To solve #1, see Is it possible to flatten sub-object fields while parsing with serde_json?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With