mod private {
pub trait CastPair<T, S> {
fn cast(n: T) -> S;
}
macro_rules! impl_cast_pairs {
($($from:ty => $($to:ty),*;)*) => {
$(
$(
impl CastPair<$from, $to> for () {
#[allow(clippy::cast_lossless)]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_possible_wrap)]
#[allow(clippy::cast_precision_loss)]
#[allow(clippy::cast_possible_truncation)]
fn cast(n: $from) -> $to {
n as $to
}
}
)*
)*
};
}
impl_cast_pairs! {
u8 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
u16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
u32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
u64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
u128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
usize => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
i8 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
i16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
i32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
i64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
i128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
isize => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64;
bool => bool, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize;
}
pub trait CastAsHelper<S>: Sized {
type P: CastPair<Self, S>;
fn cast_as_helper(self) -> S {
Self::P::cast(self)
}
}
impl<T, S> CastAsHelper<S> for T
where
(): CastPair<T, S>,
{
type P = ();
}
pub trait CastAsFixed<S>: CastAsHelper<S, P = ()> {
fn cast_as_fixed(self) -> S {
<Self as CastAsHelper<S>>::cast_as_helper(self)
}
}
impl<T: CastAsHelper<S, P = ()>, S> CastAsFixed<S> for T {}
pub trait CastFromHelper<T>: Sized {
type P: CastPair<T, Self>;
fn cast_from_helper(val: T) -> Self {
Self::P::cast(val)
}
}
impl<T, S> CastFromHelper<T> for S
where
(): CastPair<T, S>,
{
type P = ();
}
pub trait CastFromFixed<T>: CastFromHelper<T, P = ()> {
fn cast_from_fixed(val: T) -> Self {
<Self as CastFromHelper<T>>::cast_from_helper(val)
}
}
impl<T, S: CastFromHelper<T, P = ()>> CastFromFixed<T> for S {}
}
pub trait CastAs {
#[inline]
#[must_use]
fn cast_as<S>(self) -> S
where
Self: private::CastAsFixed<S>, {
<Self as private::CastAsFixed<S>>::cast_as_fixed(self)
}
}
impl<T: Primitive> CastAs for T {}
pub trait CastFrom: Sized {
fn cast_from<T>(val: T) -> Self
where
Self: private::CastFromFixed<T>, {
<Self as private::CastFromFixed<T>>::cast_from_fixed(val)
}
}
impl<T: Primitive> CastFrom for T {}
pub trait CastAsNumeric:
CastAs
+ private::CastAsFixed<u8>
+ private::CastAsFixed<u16>
+ private::CastAsFixed<u32>
+ private::CastAsFixed<u64>
+ private::CastAsFixed<u128>
+ private::CastAsFixed<usize>
+ private::CastAsFixed<i8>
+ private::CastAsFixed<i32>
+ private::CastAsFixed<i64>
+ private::CastAsFixed<i128>
+ private::CastAsFixed<isize>
+ private::CastAsFixed<f32>
+ private::CastAsFixed<f64> {
}
impl<T> CastAsNumeric for T where
T: CastAs
+ private::CastAsFixed<u8>
+ private::CastAsFixed<u16>
+ private::CastAsFixed<u32>
+ private::CastAsFixed<u64>
+ private::CastAsFixed<u128>
+ private::CastAsFixed<usize>
+ private::CastAsFixed<i8>
+ private::CastAsFixed<i32>
+ private::CastAsFixed<i64>
+ private::CastAsFixed<i128>
+ private::CastAsFixed<isize>
+ private::CastAsFixed<f32>
+ private::CastAsFixed<f64>
{
}
pub trait CastFromNumeric:
CastFrom
+ private::CastFromFixed<u8>
+ private::CastFromFixed<u16>
+ private::CastFromFixed<u32>
+ private::CastFromFixed<u64>
+ private::CastFromFixed<u128>
+ private::CastFromFixed<usize>
+ private::CastFromFixed<i8>
+ private::CastFromFixed<i32>
+ private::CastFromFixed<i64>
+ private::CastFromFixed<i128>
+ private::CastFromFixed<isize>
+ private::CastFromFixed<f32>
+ private::CastFromFixed<f64> {
}
impl<T> CastFromNumeric for T where
T: CastFrom
+ private::CastFromFixed<u8>
+ private::CastFromFixed<u16>
+ private::CastFromFixed<u32>
+ private::CastFromFixed<u64>
+ private::CastFromFixed<u128>
+ private::CastFromFixed<usize>
+ private::CastFromFixed<i8>
+ private::CastFromFixed<i32>
+ private::CastFromFixed<i64>
+ private::CastFromFixed<i128>
+ private::CastFromFixed<isize>
+ private::CastFromFixed<f32>
+ private::CastFromFixed<f64>
{
}
pub trait CastFromBool: private::CastFromFixed<bool> {}
impl<T: private::CastFromFixed<bool>> CastFromBool for T {}
pub trait Primitive: Sized {}
impl Primitive for u8 {}
impl Primitive for u16 {}
impl Primitive for u32 {}
impl Primitive for u64 {}
impl Primitive for u128 {}
impl Primitive for usize {}
impl Primitive for i8 {}
impl Primitive for i16 {}
impl Primitive for i32 {}
impl Primitive for i64 {}
impl Primitive for i128 {}
impl Primitive for isize {}
impl Primitive for f32 {}
impl Primitive for f64 {}
impl Primitive for bool {}