json
json copied to clipboard
Flatten causes maps with integer keys to fail deserialization
I'm honestly unsure whether this is a serde-json
issue or a serde
issue so feel free to redirect me if this is the wrong place.
But in the following code the addition of #[serde(flatten)]
causes roundtrip deserialization to fail when it shouldn't
use serde::{Serialize, Deserialize};
use std::collections::BTreeMap;
#[derive(Debug, Deserialize, Serialize)]
struct OuterFlattened {
// Without the flatten deserialization works, see Outer
#[serde(flatten)]
inner: Inner,
}
#[derive(Debug, Deserialize, Serialize)]
struct Outer {
// Note that inner isn't flattened
inner: Inner,
}
#[derive(Debug, Deserialize, Serialize)]
struct Inner {
map: BTreeMap<u32, String>,
}
fn main() {
let mut map = BTreeMap::new();
map.insert(1, "a".to_owned());
map.insert(2, "b".to_owned());
map.insert(3, "c".to_owned());
let outer = Outer {
inner: Inner {
map: map.clone(),
},
};
let serialized = serde_json::to_string_pretty(&outer).unwrap();
println!("Outer: {serialized}");
// Works correctly
let deserialized: Outer = serde_json::from_str(&serialized).unwrap();
println!("Outer: {deserialized:?}");
let outer_flattened = OuterFlattened {
inner: Inner { map },
};
let serialized = serde_json::to_string_pretty(&outer_flattened).unwrap();
println!("OuterFlattened: {serialized}");
// Panics trying to deserialize an string integer key
let deserialized: OuterFlattened = serde_json::from_str(&serialized).unwrap();
println!("OuterFlattened: {deserialized:?}");
}
Output:
Outer: {
"inner": {
"map": {
"1": "a",
"2": "b",
"3": "c"
}
}
}
Outer: Outer { inner: Inner { map: {1: "a", 2: "b", 3: "c"} } }
OuterFlattened: {
"map": {
"1": "a",
"2": "b",
"3": "c"
}
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"1\", expected u32", line: 7, column: 1)', src/main.rs:49:74
Removing the #[serde(flatten)]
attribute from inner
(as is done in Outer
) makes it work correctly