Reputation: 19
I try to flatten this struct, but #[serde(flatten)] doesn't work as expected
Struct example:
#[derive(Serialize, Deserialize, Debug)]
struct App {
version: String,
build_date: String,
libraries: Vec<Library>
}
#[derive(Serialize, Deserialize, Debug)]
struct Library {
#[serde(flatten)] // give me a `panic` missing field `path`
artifact: Artifact
}
#[derive(Serialize, Deserialize, Debug)]
struct Artifact {
path: String,
url: String
}
Json file which I try to deserialize:
{
"version": "0.2a",
"build_date": "2023/12/12",
"libraries": [
{
"artifact": {
"path": "somepath",
"url": "someurl"
}
},
{
"artifact": {
"path": "somepath",
"url": "someurl"
}
}
]
}
What I'm get in result (rust struct) P.S without #[serde(flatten)] it compiles, but I'm get this:
App {
version: "0.2a",
build_date: "2023/12/12",
libraries: [
Library {
artifact: Artifact {
path: "somepath",
url: "someurl",
},
},
]
}
What I'm expect from #[serde(flatten)]
I want to remove Artifact
parentness
App {
version: "0.2a",
build_date: "2023/12/12",
libraries: [
Library {
path: "somepath",
url: "someurl",
},
]
}
How I can make this? #[serde(flatten)] not works for me. Maybe it's a bug? In official serde-docs example almost same with my json. But it's not working. Have any ideas how solve this issue?
Upvotes: 0
Views: 1384
Reputation: 114518
Alternatively, if you want the flatten
attribute to have any effect, you have to make the JSON flattened. That means that the artifact
key is replaced by its contents:
{
"version": "0.2a",
"build_date": "2023/12/12",
"libraries": [
{
"path": "somepath",
"url": "someurl"
},
{
"path": "somepath",
"url": "someurl"
}
]
}
Upvotes: 0
Reputation: 71525
The JSON is not flattened, so you shouldn't put #[serde(flatten)]
. If you want the Debug
to be flattened, you can impl it manually:
use std::fmt;
#[derive(Serialize, Deserialize, Debug)]
struct App {
version: String,
build_date: String,
libraries: Vec<Library>,
}
#[derive(Serialize, Deserialize)]
struct Library {
artifact: Artifact,
}
impl fmt::Debug for Library {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.artifact.fmt(f)
}
}
#[derive(Serialize, Deserialize, Debug)]
struct Artifact {
path: String,
url: String,
}
But note that Debug
is for programmer-only output, not for user-facing output.
Upvotes: 2