Something like this would be helpful. Note that you still need to repeat about a half of arguments, this is a fundamental limit of using macros.
// test macros
macro_rules! impl_cast_same_type { ($t:ty) => (println!("impl_cast_same_type!({});", stringify!($t))) }
macro_rules! impl_cast_int_to_int { ($f:ty, $t:ty) => (println!("impl_cast_int_to_int!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_int_to_uint { ($f:ty, $t:ty) => (println!("impl_cast_int_to_uint!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_int_to_float { ($f:ty, $t:ty) => (println!("impl_cast_int_to_float!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_uint_to_int { ($f:ty, $t:ty) => (println!("impl_cast_uint_to_int!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_uint_to_uint { ($f:ty, $t:ty) => (println!("impl_cast_uint_to_uint!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_uint_to_float { ($f:ty, $t:ty) => (println!("impl_cast_uint_to_float!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_float_to_int { ($f:ty, $t:ty) => (println!("impl_cast_float_to_int!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_float_to_uint { ($f:ty, $t:ty) => (println!("impl_cast_float_to_uint!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast_float_to_float { ($f:ty, $t:ty) => (println!("impl_cast_float_to_float!({}, {});", stringify!($f), stringify!($t))) }
macro_rules! impl_cast {
(
$(i $i:ty => $(i $ii:ty),*, $(u $iu:ty),*, $(f $if_:ty),*);*;
$(u $u:ty => $(i $ui:ty),*, $(u $uu:ty),*, $(f $uf:ty),*);*;
$(f $f:ty => $(i $fi:ty),*, $(u $fu:ty),*, $(f $ff:ty),*);*;
) => ({
$(impl_cast_same_type!($i);
$(impl_cast_int_to_int!($i, $ii);)*
$(impl_cast_int_to_uint!($i, $iu);)*
$(impl_cast_int_to_float!($i, $if_);)*)*
$(impl_cast_same_type!($u);
$(impl_cast_uint_to_int!($u, $ui);)*
$(impl_cast_uint_to_uint!($u, $uu);)*
$(impl_cast_uint_to_float!($u, $uf);)*)*
$(impl_cast_same_type!($f);
$(impl_cast_float_to_int!($f, $fi);)*
$(impl_cast_float_to_uint!($f, $fu);)*
$(impl_cast_float_to_float!($f, $ff);)*)*
})
}
fn main() {
impl_cast! {
i i8 => i i16, i i32, i i64, i isize, u u8, u u16, u u32, u u64, u usize, f f32, f f64;
i i16 => i i8, i i32, i i64, i isize, u u8, u u16, u u32, u u64, u usize, f f32, f f64;
i i32 => i i8, i i16, i i64, i isize, u u8, u u16, u u32, u u64, u usize, f f32, f f64;
i i64 => i i8, i i16, i i32, i isize, u u8, u u16, u u32, u u64, u usize, f f32, f f64;
i isize => i i8, i i16, i i32, i i64, u u8, u u16, u u32, u u64, u usize, f f32, f f64;
u i8 => i i8, i i16, i i32, i i64, i isize, u u16, u u32, u u64, u usize, f f32, f f64;
u i16 => i i8, i i16, i i32, i i64, i isize, u u8, u u32, u u64, u usize, f f32, f f64;
u i32 => i i8, i i16, i i32, i i64, i isize, u u8, u u16, u u64, u usize, f f32, f f64;
u i64 => i i8, i i16, i i32, i i64, i isize, u u8, u u16, u u32, u usize, f f32, f f64;
u isize => i i8, i i16, i i32, i i64, i isize, u u8, u u16, u u32, u u64, f f32, f f64;
f f32 => i i8, i i16, i i32, i i64, i isize, u u8, u u16, u u32, u u64, u usize, f f64;
f f64 => i i8, i i16, i i32, i i64, i isize, u u8, u u16, u u32, u u64, u usize, f f32 ;
}
}