I'm using serde_json to parse JSON into structs. Everything's been great, except I recently came across some input files that have uppercased all their keys. Is there an easy way to accept both lowercase and uppercase keys? I thought maybe using the rename_all="UPPERCASE" container attribute might work, but it seems that would then only allow uppercase keys. I'm hoping not to have to write a custom deserializer.
Looks like no built in support so far.
- https://github.com/serde-rs/serde/pull/1902
- Name equality checking with `#[serde(name_eq = "..")]` by avitex · Pull Request #2161 · serde-rs/serde · GitHub
This helper crate exists, but incurs a performance penalty.
Aliases exist, but that might be quite tedious.
3 Likes
Besides the helper crate shared above, another idea I had is first reading the json as a serde_json::Value
type, and then mapping the object inside with all lowercase keys, like so:
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn main() {
let data1 = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let data2 = r#"
{
"NAME": "John Doe",
"aGe": 43,
"phoNES": [
"+44 1234567",
"+44 2345678"
]
}"#;
let p: Person = serde_json::from_str(data1).expect("Invalid JSON");
println!("Please call {} at the number {}", p.name, p.phones[0]);
let v: Value = serde_json::from_str(data2).expect("Invalid JSON");
if let Value::Object(obj) = v {
let v: Value = obj
.into_iter()
.map(|(k, v)| (k.to_lowercase(), v))
.collect();
let p: Person = serde_json::from_value(v).unwrap();
println!("Please call {} at the number {}", p.name, p.phones[0]);
}
}
But at that point you might just want to write a deserializer
Thanks. It looks like case insensitive deserialization is something that a lot of people want but has been stuck for years now.
I think I'm just going to sprinkle alias everywhere. Thanks for the info.
Looking at the code for serde_aux, it looks like that's exactly what it's doing.