My solution is to use [serde_json::Value
]
I'd still use type-driven serialization, wrapping the potentially-missing field in an Option
.
use serde::Deserialize; // 1.0.101
use serde_json; // 1.0.40
#[derive(Debug, Deserialize)]
struct Data {
required: i32,
missing: Option<String>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = r#"{"required": 42, "extra": true}"#;
let data = serde_json::from_str::<Data>(data)?;
println!("{:?}", data);
let data = r#"{"required": 42, "extra": true, "missing": "cow"}"#;
let data = serde_json::from_str::<Data>(data)?;
println!("{:?}", data);
Ok(())
}
Data { required: 42, missing: None }
Data { required: 42, missing: Some("cow") }
If you have fields where the name cannot be known at compile time, you can use serde_json::Value
in addition to this solution. See How can I use Serde's custom (de)serialization to update a subset of arbitrary input?
See also: