You could introduce a trait for this purpose and only implement it for the relevant types.
pub trait NotBigUInt {
fn as_u128(self) -> u128;
}
impl NotBigUInt for u8 {
fn as_u128(self) -> u128 {
self as u128
}
}
impl NotBigUInt for u16 {
fn as_u128(self) -> u128 {
self as u128
}
}
impl NotBigUInt for u32 {
fn as_u128(self) -> u128 {
self as u128
}
}
impl NotBigUInt for u64 {
fn as_u128(self) -> u128 {
self as u128
}
}
#[inline(always)]
pub fn multiply_u128<T: NotBigUInt>(
a: T,
b: T,
result: &mut [u64],
) {
let r = a.as_u128() * b.as_u128();
//fill result with 64 bit chunks
result[0] = r as u64;
}
fn main() {
let mut r = [0_u64; 1];
multiply_u128(1_u8, 1_u8, &mut r);
multiply_u128(1_u16, 1_u16, &mut r);
multiply_u128(1_u32, 1_u32, &mut r);
multiply_u128(1_u64, 1_u64, &mut r);
// multiply_u128(1_u128, 1_u128, &mut r);
}