Enum with tuple as value - serializing with serde

So my enums currently look something like this:

#[derive(Debug, Deserialize, Serialize)]
pub enum Payload {
    This,
    That,
}

#[derive(Debug, Deserialize, Serialize)]
pub enum Variant {
    One,
    Two(f64, Payload),
}

I'm using serde to serialize the Variant enum into Toml and then deserialize it back again. In the case of Variant::One the Toml becomes variant = "One", which it can successfully deserialize back again. However, with Variant::Two(42.0, Payload::This) I get variant = [42.0, "This"], which serde can't deserialize properly.

expected string or inline table, found array for key `variant`at line 3 column 11

I've never tried to use a tuple as an enum payload with serde, but I'm used to things "just working" with this library. Is there a way to fix this short of rethinking my data structure and using a struct with named fields?

I think you need to choose where the enum tag is stored as described in the serde docs here. It's kinda unfortunate the default choice (which is supposed to be externally tagged, except it didn't actually store the tag anywhere?) fails to make a round-trip through serialization in this case..

Thanks, I was actually looking at that but I didn't find a way around without modifying my data structure. When I tried to add #[serde(tag = "variant")] the compiler informed me that tag = "..." cannot be used with tuple variants. It turned out to not be a huge deal to change the data structure to just have two optional values, as it only impacted the code in three other places.

This should definitely work, and the default external tagging should indeed write the variant name. It legitimately looks like a bug in the TOML serializer.

When I have some time I'll investigate further and if it looks like it is indeed a bug, I'll get in touch with the author of the TOML serializer. I went a different way just to get my application working, but I hate to think I might have found a bug and then not follow up.

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.