Retrieve deeply nested value with serde

The issue is simple
I have this JSON

{
    "_links": {
        "item": {
            "href": "/leaderboard/08/1AE1A7D894960B38E09E7494373378D87305A163/00.json"
        }
    },
    "name": "Luigi Circuit",
    "authors": [
        "Nintendo"
    ],
    "slotId": 8,
    "correctSlotId": 8,
    "inCtgp": true,
    "defaultTrack": true,
    "200cc": false,
    "trackId": "1AE1A7D894960B38E09E7494373378D87305A163",
    "ghostCount": 88241,
    "uniquePlayers": 12628,
    "popularity": 161,
    "lastChanged": "2024-03-02T15:22:09Z",
    "fastestTime": "01:08.732071723104",
    "fastestTimeSimple": "01:08.733",
    "fastestTimeLastChange": "2023-09-30T17:32:08Z"
}

And I have defined this struct

#[derive(Debug, Clone, Deserialize)]
#[allow(non_snake_case)]
struct ChadsoftJSONTrack {
    lastChanged: String,
    trackId: String,

    #[serde(default)]
    categoryId: u8, // defaults to 0

    #[serde(default, alias="200cc")]
    cc200: bool, // defaults to false

    href: String
}

Is there a way I can define href as being that nested value in the struct? At first I thought flatten would do that, but turns out it meant something completely different from usual.

(I know I could just define three different structs, but it looked very ugly to read)

Since you only want to deserialize you can use serde-query for this. You specify a path to the field for deserializing, something like #[query("._links.item.href")].

2 Likes

Thanks a lot! This is very much what I need, I'm not a fan of how it strips out the implicit look up for fields, but this will do for the time being.