Skip to content

Instantly share code, notes, and snippets.

@piedoom
Created September 23, 2018 19:36
Show Gist options
  • Save piedoom/480a404b2e5a9aacfa5a284bbe1bec31 to your computer and use it in GitHub Desktop.
Save piedoom/480a404b2e5a9aacfa5a284bbe1bec31 to your computer and use it in GitHub Desktop.
serde parsing
#[serde(rename_all = "snake_case")]
#[derive(Serialize, Deserialize, Debug)]
pub enum Response {
Posts(Vec<Post>),
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
pub enum Post {
Text(Text),
Photo(Photo),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Text {
info: PostInfo, // is there a way to do something like this?
title: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Photo {
info: PostInfo,
photo_url: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PostInfo {
id: usize,
url: String,
}
[
{ "id": 1, "url": "some_url", "title": "my title", "type": "text" },
{ "id": 1, "url": "some_url", "photo_url": "example.com/pic.jpg", "type": "photo" }
]

Goals

I'm creating a Tumblr API wrapper. Unfortunately the way it's designed does not really mesh with Rust's data representation.

Serde has introduced the awesome tag decorator which makes sorting enums very easy when it is internally tagged.
However, Tumblr's types only differ by a few fields. For instance, all posts have the following fields, no matter the type:

id,
url,
timestamp,
date,
format,
... etc

However, depending on the post type, they may also contain other data. Photo types contain "photo_url", while text types include "title". Due to this, I can write my data models like this:

pub enum TextPost {
    id: usize,
    ... all other generic fields ...
    title: String,
}

pub enum PhotoPost {
    id: usize,
    ... all other generic fields ...
    photo_url: String,
}

However, that would lead to a lot of duplication! I was wondering if there is a way to consolidate that information on to another structure. For example, take the models.rs file above. I want to store all the generic fields in a struct with the field info. However, since the JSON does not put all generic fields in any structure, I cannot use this approach. Is there a way I can have minimal duplication while still obtaining all the generic info? Is there a serde decorator I can apply to the "info" field that tells it "hey, I want all the fields on this exposed on a root level when deserializing!"

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment