1pub trait Numeric: Clone + Copy + PartialEq + PartialOrd + 'static {
3 const INTEGRAL: bool;
5
6 const MIN: Self;
8
9 const MAX: Self;
11
12 fn to_f64(self) -> f64;
13
14 fn from_f64(num: f64) -> Self;
15}
16
17macro_rules! impl_numeric_float {
18 ($t: ident) => {
19 impl Numeric for $t {
20 const INTEGRAL: bool = false;
21 const MIN: Self = $t::MIN;
22 const MAX: Self = $t::MAX;
23
24 #[inline(always)]
25 fn to_f64(self) -> f64 {
26 #[allow(trivial_numeric_casts)]
27 {
28 self as f64
29 }
30 }
31
32 #[inline(always)]
33 fn from_f64(num: f64) -> Self {
34 #[allow(trivial_numeric_casts)]
35 {
36 num as Self
37 }
38 }
39 }
40 };
41}
42
43macro_rules! impl_numeric_integer {
44 ($t: ident) => {
45 impl Numeric for $t {
46 const INTEGRAL: bool = true;
47 const MIN: Self = $t::MIN;
48 const MAX: Self = $t::MAX;
49
50 #[inline(always)]
51 fn to_f64(self) -> f64 {
52 self as f64
53 }
54
55 #[inline(always)]
56 fn from_f64(num: f64) -> Self {
57 num as Self
58 }
59 }
60 };
61}
62
63macro_rules! impl_numeric_non_zero_unsigned {
64 ($t: path) => {
65 impl Numeric for $t {
66 const INTEGRAL: bool = true;
67 const MIN: Self = Self::MIN;
68 const MAX: Self = Self::MAX;
69
70 #[inline(always)]
71 fn to_f64(self) -> f64 {
72 self.get() as f64
73 }
74
75 #[inline(always)]
76 fn from_f64(num: f64) -> Self {
77 Self::new(num.round().max(1.0) as _).unwrap_or(Self::MIN)
78 }
79 }
80 };
81}
82
83impl_numeric_float!(f32);
84impl_numeric_float!(f64);
85impl_numeric_integer!(i8);
86impl_numeric_integer!(u8);
87impl_numeric_integer!(i16);
88impl_numeric_integer!(u16);
89impl_numeric_integer!(i32);
90impl_numeric_integer!(u32);
91impl_numeric_integer!(i64);
92impl_numeric_integer!(u64);
93impl_numeric_integer!(isize);
94impl_numeric_integer!(usize);
95impl_numeric_non_zero_unsigned!(std::num::NonZeroU8);
96impl_numeric_non_zero_unsigned!(std::num::NonZeroU16);
97impl_numeric_non_zero_unsigned!(std::num::NonZeroU32);
98impl_numeric_non_zero_unsigned!(std::num::NonZeroU64);
99impl_numeric_non_zero_unsigned!(std::num::NonZeroU128);
100impl_numeric_non_zero_unsigned!(std::num::NonZeroUsize);