Is it possible to create an enum variant from a tuple without decomposing the tuple?

To keep it short, I have the following enum:

pub enum Enum {
    Pair(u8, u8),
    F(f32),
    Array([u8; 6]),
}

Is is possible to create a Enum::Pair from a (u8, u8)?

let pair = (3,4);
let variant = Enum::Pair(pair);

This doesn't work because Enum::Pair() expect 2 arguments. I don't think that rust as the equivalent of the star operator in python either. Is there another way to do it?

You could impl From<(u8, u8)> for Enum, and then use Enum::from(pair). But still, this does require decomposing at some level.

1 Like

The only ways involve creating a method that internally distributes the tuple fields to the enum value.

The underlying problem here is that the type of the anonymous tuple let pair = (3,4), which might be realized as a pair of i32s, is different from the type of the enum variant Enum::Pair, which is composed of u8s.

If you don't need to do this very often you could just decompose the tuple manually and recompose it as the desired variant:

let variant = Enum::Pair(pair.0, pair.1);

Edit: That doesn't work without a type coercion, since pair.0 might be an i32 rather than a u8.

You can sort of emulate the Python star operator by using the unstable function traits directly, because they currently represent their arguments as a single tuple.

#![feature(fn_traits)]

#[allow(unused)]
#[derive(Debug)]
enum Enum {
    Pair(u8, u8),
    F(f32),
    Array([u8; 6]),
}

fn main() {
    let pair = (3, 4);
    let variant = Fn::call(&Enum::Pair, pair);
    dbg!(variant);
}

playground

Even then, it's not really the same as Python, because this can't be mixed with other arguments.

1 Like

Thanks all. As I feared, there is no easy way to do it in stable.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.