I'm writing a library that deals with numerical attributes. For this I have created a trait for all the number primitives:
trait Sealed {}
#[allow(private_bounds, reason = "To seal trait Number")]
pub trait Number: Sealed
+ Sized + Clone + Copy
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
{}
Assume that this trait is implemented for all numerical types (u8, u16, etc...). It's also sealed so that no other type can implement it.
Naturally, you can convert numerical primitives from and to each other using the as keyword, it's a simple cast. However, if all we know about a type T is that it implements Number, this cast no longer works.
To address this, I have created another trait that allows conversion between Number instances:
pub trait ConvertNumber<T>: Number
where
T: Number
{
fn convert(self) -> T;
}
Again, assume that this trait is implemented for every pair of numerical primitives.
This now works, but every time I need conversion between different types that implement Number, I have to add an extra constraint to ConvertNumber, which can lead to the API leaking implementation details.
My question is, can I make the compiler know that every T: Number is convertible to any other type that implements Number without extra constraints?
ConvertNumbertrait, I'm just looking for any solution that works.ConvertNumber<u8> + ConvertNumber<u16> + ..toNumber(Number is sealed, after all, so the set of instances is finite). Otherwise you can useInto<VariantNumber>whereenum VariantNumber { U8(u8), U16(u16), ... }