serde-ignored
serde-ignored copied to clipboard
Flattened fields
It seems that ignored fields are not detected if the structure contains the flattened field. It probably relates to the serde issue, that flatten
and deny_unkown_fields
cannot be combined (https://github.com/jonasbb/serde-rs.github.io/commit/af0e2e68c98cd2a8411cf194156aabb8316f9cea). Is there a way to make serde-ignored work with flattened fields?
I just ran into the same problem. Here is an example that demonstrates the issue:
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Test1 {}
#[derive(Debug, Deserialize)]
struct Test2 {
#[serde(flatten)]
more: More,
}
#[derive(Debug, Deserialize)]
struct More {
anything: u16,
}
fn test<'de, T: Deserialize<'de> + std::fmt::Debug>(json: &'de str) -> Option<String> {
let jd = &mut serde_json::Deserializer::from_str(json);
let mut unknown = None;
let _: T = serde_ignored::deserialize(jd, |path| {
unknown.replace(path.to_string());
})
.unwrap();
unknown
}
fn main() {
// Succeeds:
assert_eq!(test::<Test1>(r#"{"test1": 42}"#), Some("test1".to_string()));
// Fails:
assert_eq!(
test::<Test2>(r#"{"anything": 42, "test2": 42}"#),
Some("test2".to_string())
);
}
Perhaps something like this can be a workaround? I'm just not sure if it's something we can reliably depend on.
use std::collections::BTreeMap as Map;
use serde_json::Value;
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
struct Inner {
a: u32,
b: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct InnerWithExtra {
#[serde(flatten)]
inner: Inner,
#[serde(flatten)]
other: Map<String, Value>,
}
fn main() {
let x: InnerWithExtra = serde_json::from_str(
r#"{
"a": 123,
"b": "foo",
"unknown": "mystery"
}"#
).unwrap();
println!("{:?}", x);
}