I am researching how to create what dtolnay calls a "Deserializer adapter" for duplicate keys/fields in this issue comment on GitHub:
This should be implemented outside of Serde as a Deserializer adapter -- similar to how serde-ignored or serde-stacker wrap an existing Deserializer into their own Deserializer with extra behavior. Possible usage:
let mut j = serde_json::Deserializer::from_str(input); let de = WhenDuplicateField::keep_first(&mut j); let t = T::deserialize(de)?;|
My problem is that I use a service that I can't control, that sometimes outputs duplicate fields in JSON output.
{
"key": "abc",
"data": 5,
"key": "abc",
}
My first idea was that someone else must have had the same problem before, and published an adapter on crates.io already, but I could not find one. If one exists, I would happily use it.
My second idea was to create the adapter myself, with the idea that I need to keep track of the JSON field keys the wrapping Deserializer sees, and then just skip delegating to the serde_json::Deserializer
in those cases.
I took a look at serde-ignored. There is an impl for MapAccess
that has next_key_seed
. In that one it's possible to keep track of the encountered keys, giving CaptureKey
an &mut HashSet
.
What I think I need help with, is - at what layer can you skip or reject certain keys?
Thanks.
Edit: To be clear, I want to deserialize into a struct, not a BTreeMap. Something like this:
#[derive(Deserialize)]
struct S {
key: String,
data: u8,
}