Is there a simple way to run whole tuples of scalar values ​​at a time?

advertisements

I want to cast a (u16, u16) to a (f32, f32). This is what I tried:

let tuple1 = (5u16, 8u16);
let tuple2 = tuple1 as (f32, f32);

Ideally, I would like to avoid writing

let tuple2 = (tuple1.0 as f32, tuple1.1 as f32);


There's no built-in way to do this, but one can do it with a macro:

macro_rules! tuple_as {
    ($t: expr, ($($ty: ident),*)) => {
        {
            let ($($ty,)*) = $t;
            ($($ty as $ty,)*)
        }
    }
}

fn main() {
    let t: (u8, char, isize) = (97, 'a', -1);

    let other = tuple_as!(t, (char, i32, i8));

    println!("{:?}", other);
}

Prints ('a', 97, -1).

The macro only works for casting between types with names that are a single identifier (that's what the : ident refers to), since it reuses those names for binding to the elements of the source tuple to be able to cast them. All primitive types are valid single identifiers, so it works well for those.