0

I am trying to deserialize JSON that is received from Web API and has some unnecessarily deep structure.

With serde, is it possible to deserialize JSON like:

{
    "unnecessarily": {
        "deep": {
            "structure": {
                "data1": 0
            }
        }
    },
    "data2": 0
}

to rust struct:

struct Data {
   data1: usize,
   data2: usize,
}

without manually implementing Deserialize?

If it is impossible, are there any other suitable crates?

  • You can define several structs that mimic the structure of your JSON, then use the [`from`](https://serde.rs/container-attrs.html#from) tag to convert automatically into the flat struct. – Jmb Apr 08 '20 at 06:43

1 Answers1

2

You can use serde's derive macro to generate implementations of Serialize and Deserialize traits

use serde::Deserialize;

#[derive(Deserialize)]
struct Data {
   data1: usize,
   data2: usize,
}

If the JSON structure is not known ahead of time, you can deserialize to serde_json::Value and work with this

use serde_json::{Result, Value};
fn example() -> Result<()> {
    let data = r#"
        {
          "unnecessarily": {
            "deep": {
              "structure": {
                "data1": 0
              }
            }
          },
          "data2": 0
        }"#;

    let v: Value = serde_json::from_str(data)?;

    let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?;

    Ok(())
}
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • The JSON in my question is simplified and the actual JSON is much more complex, so this approach requires a lot of code like `let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?;` Is there a better way? – mkihr_ojisan Apr 08 '20 at 06:57
  • @mkihr_ojisan Well I guess in one or the other way you have to tell your code which path to go to find the data. If you don't write it like `let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?;` you have to write it somewhere else.—I read the suggestion of Russ in a way that you parse generically and then write a wrapper/converter to convert it to your nicer Rust data structures. – Matthias Wimmer Apr 08 '20 at 07:37