Json serialization - deserializing a single key only

Hi.
I'm trying to parse a JSON that looks like this:

{
    "itemId": "some-id",
    "title": "redacted",
    "leafCategoryIds": [
        "0000000"
    ],
    "categories": [
        {
            "categoryId": "000000",
            "categoryName": "redacted"
        }
    ],
    "image": {
        "imageUrl": "redacted"
    }
}

I have these structures:

#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct SearchItem {
    #[serde(rename = "itemId")]
    id: String,
    title: String,
    // leafCategoryIds - dont care
    categories: Vec<Category>,
    image: Image,
}

#[derive(Debug, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Image {
    #[serde(rename = "imageUrl")]
    url: String,
}

Is there any way to parse the image key without having to create a wrapper struct (Image) just because of a single key? I only need the imageUrl. So for example the SearchItem structure would look something like this:

#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct SearchItemSimplified {
    #[serde(rename = "itemId")]
    id: String,
    title: String,
    // leafCategoryIds
    categories: Vec<Category>,
    // image->imageUrl
    image: String,
}

In theory this could be possible with some custom deserialization magic, but it will probably not be worth the effort. Why don't you just

impl SearchItem {
    pub fn image_url(&self) -> &str {
        &self.image.url
    }
}

?

2 Likes

You can use deserialize_with:

#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct SearchItem {
    #[serde(rename = "itemId")]
    id: String,
    title: String,
    #[serde(deserialize_with = "serde_image")]
    image: String,
}

fn serde_image<'de, D>(de: D) -> Result<String, D::Error>
where
    D: serde::Deserializer<'de>,
{
    Ok(Image::deserialize(de)?.url)
}

#[derive(Debug, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
struct Image {
    #[serde(rename = "imageUrl")]
    url: String,
}
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.