Conditionally decoding JSON based on a field in the JSON Conditionally decoding JSON based on a field in the JSON json json

Conditionally decoding JSON based on a field in the JSON


You can use the existing enum deserialization. I'll give a step by step example to deserialize your format to the following enum:

#[derive(Debug, PartialEq, Eq, Deserialize)]enum MyType {    A {gar: ()},    B {test: i32},    C {blub: String},}
  1. Start with an example json string:

    let json = r#"{"type": "B", "test": 42}"#;
  2. Turn it into a Value enum

    let mut json: serde_json::Value = serde_json::from_str(json).unwrap();
  3. Rip out the type field

    let type_ = {    let obj = json.as_object_mut().expect("object");    let type_ = obj.remove("type").expect("`type` field");    if let serde_json::Value::String(s) = type_ {        s    } else {        panic!("type field not a string");    }};
  4. Create the "proper" enum json. A struct with a single field where the name of the field is the enum variant and the value of the field is the variant value

    let mut enum_obj = std::collections::BTreeMap::new();enum_obj.insert(type_, json);let json = serde_json::Value::Object(enum_obj);
  5. Use the generated json deserializer to turn the json into a value of your enum

    let obj: MyType = serde_json::from_value(json).unwrap();