Use enum variant as only its struct value

I have an app that has 2 functions that take a type we’ll call T and U. They are stored in an enum that looks like this:

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum V {
    T { w: String },
    U { x: i32 },
}

This is pretty simplified, the real enum has a lot of nested structs. What I’m wondering is, can I in any way get the inner value (in a match or otherwise) like I could with a tuple? Could I use a tuple for this? Here’s the functions:

fn t(param: V/*::T*/) {}
fn u(param: V/*::U*/) {}

I can’t just use the ::* to do it, because enum variants aren’t considered types. If this isn’t possible, I can just refactor to pass the values into the function instead. Any help would be great, thanks!

1 Like

Enum variants are not standalone types unfortunately. You need to create the structs yourself:

struct T  { w: String }
struct U  { x: i32 }

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum V {
    T(T),
    U(U),
}

The best way to do this is probably:

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum V {
    T(T),
    U(U),
}

#[derive(Serialize, Deserialize)]
struct T {
    w: String,
}

#[derive(Serialize, Deserialize)]
struct U {
    x: i32,
}

Note the #[serde(transparent)], which should have the structs de/serialize with the same representation as you had before (if that’s necessary. Considering you left the serde attributes on the enum in the OP, I assumed it could be important.)

Edit: the #[serde(transparent)] actually changes the representation and is wrong. See my post below Use enum variant as only its struct value - #5 by cod10129.

Prior art: std::net::IpAddr (whose serde implementation is actually rather complicated, in JSON it would appear as "127.0.0.1" or "::1", but if the serialization format isn’t meant to be human readable it just serializes the bytes of the address directly).

1 Like

I just tried this: it looks promising, but it didn’t work in the playground. Is it something with serde_json?

Permalink: Rust Playground

Edit: Updated link without old testing code.

That's my bad. I guess I didn't realize how serde modeled untagged enums with struct variants (like V in your OP). Just remove the #[serde(transparent)] and it works (Rust Playground). I edited my post above to fix the error.