How to parse JSON with weird structure?

I am trying to parse a JSON struct using serde. This is how the JSON looks like:

{
  "": {
    "yb-3.local:9000": {
      "time_since_hb": "0.3s",
      "zone": "local"
    },
    "yb-1.local:9000": {
      "time_since_hb": "0.6s",
      "zone": "local"
    }
  }
}

The problems I identified are:

  • I cannot map an empty field name to a struct as far as I could see.
  • The second level field names are hostnames, and thus dynamic, so I cannot know these.
  • The hostnames contains statistics per host, for which the number of hosts is dynamic, but they are not provided as an array ().

I found a way to get past the empty field name by using:

    let tse: Value = serde_json::from_str(&tserver).unwrap();
    println!("json = {:?}", tse.get("").unwrap());

Is there a way to get the field names of the host converted to a field name 'hostname', and the field name as host, and all the hostnames converted to an array?

You could try manually implementing the Deserialize traits (a guide is given on the serde site).

You don't need any manual implementations.

#[derive(Debug, serde::Deserialize)]
struct Message {
    #[serde(rename = "")]
    hosts: HashMap<String, Host>,
}

#[derive(Debug, serde::Deserialize)]
struct Host {
    time_since_hb: String,
    zone: String,
}

https://serde.rs contains all the attributes the serde derive supports. To parse the time_since_hb as a std::time::Duration you can use the humantime_serde crate, but the crate is not supported on the playground.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.