Need help Deserializing json data from weather station

Hi, I am trying to extract some weather station data to put in a csv file, but I'm a bit lost in the desiarilizing stufff.

Here is the output of the API call

{
    "code": 0,
    "msg": "success",
    "time": "1655152323",
    "data": {
        "rainfall": {
            "rain_rate": {
                "unit": "in\/hr",
                "list": {
                    "1651377600": "0.00",
                    "1651377900": "0.00",
                    "1651378200": "0.00",
                    "1651378500": "0.00",
                    "1651378800": "0.00",
snip...

I want to get the data under "list".

Not sure if it's the best way to deal with this, but I tried to use a cascade of structs with Deserialize

#[derive(Debug, Serialize, Deserialize)]
struct StationData {
    data: DataRainfall,
}

#[derive(Debug, Serialize, Deserialize)]
struct DataRainfall {
    rainfall: Rainfall,
}

#[derive(Debug, Serialize, Deserialize)]
struct Rainfall {
    rain_rate: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct DailyRainRate {
    unit: String,
    list: Vec<Vec<String>>,
}

The data inside "List" would correspond to the struct DailyRainRate, but the compiler complains that it is receiving a Map instead of a String. Since it is not a named field, I am not sure how to deal with it.

Any help is appreciated :slight_smile:

A json object can be deserialized either into a struct or into a HashMap.
So here, rain_rate cannot be deserialized into a String, I think you should define another struct for that.
For list, since all keys are String and all values are also String, you can use HashMap<String, String>.

I'm assuming the keys are timestamps of some kind / that order matters, in which case you probably want a BTreeMap and not a HashMap (if there's no better way to just rip out the values only).

Where does DailyRainRate get used? As far as I can tell it doesn't show up in your hierarchy of structs at all.

It seems to me that you should change Rainfall to hold a DailyRainRate, i.e.

#[derive(Debug, Serialize, Deserialize)]
struct Rainfall {
    rain_rate: DailyRainRate,
}

You will probably also get an error that list is not a Vec<Vec<String>>, which I would fix by changing list to be a HashMap<String,String>, but that is speculation.

Indeed, in my code Rainfall point to DailyRainRate. I was doing some fiddling and forgot to put it back as it should.

1 Like

Thanks! Indeed they are time stamps and the order does matter.

This now seems to work fine

#[derive(Debug, Serialize, Deserialize)]
struct StationData {
    data: DataRainfall,
}

#[derive(Debug, Serialize, Deserialize)]
struct DataRainfall {
    rainfall: Rainfall,
}

#[derive(Debug, Serialize, Deserialize)]
struct Rainfall {
    rain_rate: DailyRainRate,
}
#[derive(Debug, Serialize, Deserialize)]
struct DailyRainRate {
    unit: String,
    list: BTreeMap<String, String>,
}

Thanks for the other replies too, a hashmap would have worked, if not for the ordering thing, which I forgot to mention.

Thanks all! :slight_smile:

1 Like

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.