use std::fmt::{Debug, Display};
use num_traits::{AsPrimitive, PrimInt};
pub trait CastFromPrimitive<T>: Copy + 'static {
fn cast_from(v: T) -> Self;
}
macro_rules! impl_cast_from_primitive {
( $T:ty => $U:ty ) => {
impl CastFromPrimitive<$U> for $T {
#[inline(always)]
fn cast_from(v: $U) -> Self { v as Self }
}
};
( $T:ty => { $( $U:ty ),* } ) => {
$( impl_cast_from_primitive!($T => $U); )*
};
}
impl_cast_from_primitive!(u8 => { u32, u64, usize });
impl_cast_from_primitive!(u8 => { i8, i64, isize });
impl_cast_from_primitive!(u16 => { u32, u64, usize });
impl_cast_from_primitive!(u16 => { i8, i64, isize });
impl_cast_from_primitive!(i16 => { u32, u64, usize });
impl_cast_from_primitive!(i16 => { i8, i64, isize });
impl_cast_from_primitive!(i32 => { u32, u64, usize });
impl_cast_from_primitive!(i32 => { i8, i64, isize });
pub trait RegisteredPrimitive:
PrimInt
+ AsPrimitive<u8>
+ AsPrimitive<i16>
+ AsPrimitive<u16>
+ AsPrimitive<i32>
+ AsPrimitive<u32>
+ AsPrimitive<usize>
+ CastFromPrimitive<u8>
+ CastFromPrimitive<i16>
+ CastFromPrimitive<u16>
+ CastFromPrimitive<i32>
+ CastFromPrimitive<u32>
+ CastFromPrimitive<usize>
{
}
impl RegisteredPrimitive for u8 {}
impl RegisteredPrimitive for u16 {}
impl RegisteredPrimitive for i16 {}
impl RegisteredPrimitive for i32 {}
macro_rules! impl_cast_from_pixel_to_primitive {
( $T:ty ) => {
impl<T: RegisteredPrimitive> CastFromPrimitive<T> for $T {
#[inline(always)]
fn cast_from(v: T) -> Self {
v.as_()
}
}
};
}
impl_cast_from_pixel_to_primitive!(u8);
impl_cast_from_pixel_to_primitive!(i16);
impl_cast_from_pixel_to_primitive!(u16);
impl_cast_from_pixel_to_primitive!(i32);
impl_cast_from_pixel_to_primitive!(u32);
pub enum PixelType {
U8,
U16,
}
pub trait Pixel:
RegisteredPrimitive + Into<u32> + Into<i32> + Debug + Display + Send + Sync + 'static
{
fn type_enum() -> PixelType;
}
impl Pixel for u8 {
#[inline]
fn type_enum() -> PixelType {
PixelType::U8
}
}
impl Pixel for u16 {
#[inline]
fn type_enum() -> PixelType {
PixelType::U16
}
}