VP.
VP.

Reputation: 16685

How to use Serde to (de)serialize a tuple struct from JSON named values instead of an array?

I have a JSON object:

{ "min": 2, "max": 15 }

I'd like to parse it to this tuple struct:

#[derive(Serialize, Deserialize, Debug)]
struct TeamSize(pub i64, pub i64);
#[derive(Serialize, Deserialize, Debug)]
struct Match {
    size: TeamSize,
}

The current Serde serialization mechanism does not seem to provide the functionality of (de)serializing a tuple structure from named values instead of an array.

The generated (de)serialization mechanism expects the following:

{"size": [2, 15]}

I've tried to use Serde attributes, but I can't find one that does what I want:

#[derive(Serialize, Deserialize, Debug)]
pub struct TeamSize(
    #[serde(rename = "min")]
    pub i64,
    #[serde(rename = "max")]
    pub i64
);

How to parse it? Should I implement everything by myself?

I've opened an issue on the Serde repository.

Upvotes: 3

Views: 5935

Answers (1)

Cobrand
Cobrand

Reputation: 133

#[derive(Serialize, Deserialize, Debug)]
pub struct TeamSize(
    #[serde(rename = "min")]
    pub i64,
    #[serde(rename = "max")]
    pub i64
);

is not valid code, the Serde rename attribute only renames what is being serialized and deserialized, it does not change your code. In a tuple struct (your first one), you can (and must) omit names because you simply access them via self.0 and self.1, but a struct doesn't have a first or a second field, so you must add a name to them.

Like so:

#[derive(Serialize, Deserialize, Debug)]
pub struct TeamSize {
    pub max: i64,
    pub min: i64,
};

Since the name of your attribute is the name of the JSON property (both min and max), you do not need to use serde(rename). You would have needed it if your Rust struct used the fields value_max and value_min but your JSON still used max and min.

If you absolutely want to parse it to a tuple struct, you must implement Serialize and Deserialize for your custom struct yourself. I don't think it's worth the hassle though, just switch to a struct instead of a tuple struct.

Upvotes: 6

Related Questions