#[serde(rename)]
seems to be the right option, but the documentation does not state if it is possible or how to do it.
This JSON object:
{
"name" : "myobject"
"info" :
{
"counter" : "3"
"foo" : "bar"
}
}
The corresponding flat Rust struct should be:
#[derive(Deserialize)]
struct Object {
name: String,
#[serde(rename="info.counter")] // wrong syntax here !!
count: i32,
#[serde(rename="info::foo")] // neither this works
foo: String,
}
There is no built-in way to do this with attributes, but you can write your own Deserialize
impl for your Object
type that deserializes first to some intermediate helper representation and then rearranges the data into the desired struct.
#[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());
}
The output is:
Object {
name: "myobject",
count: 3,
foo: "bar"
}
There are three materially different places where insignificant nesting arises:
All three require different approaches. #1 is observed in this question.
To solve #2 or #3, see Is there a way to omit wrapper/root objects when deserializing objects with Serde?
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