1use std::fmt::{Debug, Display};
2
3use num_traits::{AsPrimitive, PrimInt};
4
5pub trait CastFromPrimitive<T>: Copy + 'static {
7 fn cast_from(v: T) -> Self;
9}
10
11macro_rules! impl_cast_from_primitive {
12 ( $T:ty => $U:ty ) => {
13 impl CastFromPrimitive<$U> for $T {
14 #[inline(always)]
15 fn cast_from(v: $U) -> Self { v as Self }
16 }
17 };
18 ( $T:ty => { $( $U:ty ),* } ) => {
19 $( impl_cast_from_primitive!($T => $U); )*
20 };
21 }
22
23impl_cast_from_primitive!(u8 => { u32, u64, usize });
26impl_cast_from_primitive!(u8 => { i8, i64, isize });
27impl_cast_from_primitive!(u16 => { u32, u64, usize });
28impl_cast_from_primitive!(u16 => { i8, i64, isize });
29impl_cast_from_primitive!(i16 => { u32, u64, usize });
30impl_cast_from_primitive!(i16 => { i8, i64, isize });
31impl_cast_from_primitive!(i32 => { u32, u64, usize });
32impl_cast_from_primitive!(i32 => { i8, i64, isize });
33
34pub trait RegisteredPrimitive:
35 PrimInt
36 + AsPrimitive<u8>
37 + AsPrimitive<i16>
38 + AsPrimitive<u16>
39 + AsPrimitive<i32>
40 + AsPrimitive<u32>
41 + AsPrimitive<usize>
42 + CastFromPrimitive<u8>
43 + CastFromPrimitive<i16>
44 + CastFromPrimitive<u16>
45 + CastFromPrimitive<i32>
46 + CastFromPrimitive<u32>
47 + CastFromPrimitive<usize>
48{
49}
50
51impl RegisteredPrimitive for u8 {}
52impl RegisteredPrimitive for u16 {}
53impl RegisteredPrimitive for i16 {}
54impl RegisteredPrimitive for i32 {}
55
56macro_rules! impl_cast_from_pixel_to_primitive {
57 ( $T:ty ) => {
58 impl<T: RegisteredPrimitive> CastFromPrimitive<T> for $T {
59 #[inline(always)]
60 fn cast_from(v: T) -> Self {
61 v.as_()
62 }
63 }
64 };
65}
66
67impl_cast_from_pixel_to_primitive!(u8);
68impl_cast_from_pixel_to_primitive!(i16);
69impl_cast_from_pixel_to_primitive!(u16);
70impl_cast_from_pixel_to_primitive!(i32);
71impl_cast_from_pixel_to_primitive!(u32);
72
73pub enum PixelType {
75 U8,
77 U16,
79}
80
81pub trait Pixel:
83 RegisteredPrimitive + Into<u32> + Into<i32> + Debug + Display + Send + Sync + 'static
84{
85 fn type_enum() -> PixelType;
89}
90
91impl Pixel for u8 {
92 #[inline]
93 fn type_enum() -> PixelType {
94 PixelType::U8
95 }
96}
97
98impl Pixel for u16 {
99 #[inline]
100 fn type_enum() -> PixelType {
101 PixelType::U16
102 }
103}