rat_widget/
range_op.rs

1//!
2//! Bounded numeric operations.
3//!
4
5/// Bounded numeric add and subtract.
6pub trait RangeOp
7where
8    Self: Sized,
9{
10    type Step;
11
12    /// Addition. Bounded to min/max.
13    fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self;
14
15    /// Subtraction. Bounded to min/max.
16    fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self;
17}
18
19macro_rules! u_range_op {
20    ($value_ty:ty, $step_ty:ty) => {
21        impl RangeOp for $value_ty {
22            type Step = $step_ty;
23
24            #[inline(always)]
25            fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
26                self.saturating_add(delta).clamp(bounds.0, bounds.1)
27            }
28
29            #[inline(always)]
30            fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
31                self.saturating_sub(delta).clamp(bounds.0, bounds.1)
32            }
33        }
34    };
35}
36
37macro_rules! i_range_op {
38    ($value_ty:ty, $step_ty:ty) => {
39        impl RangeOp for $value_ty {
40            type Step = $step_ty;
41
42            #[inline(always)]
43            fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
44                self.saturating_add_unsigned(delta)
45                    .clamp(bounds.0, bounds.1)
46            }
47
48            #[inline(always)]
49            fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
50                self.saturating_sub_unsigned(delta)
51                    .clamp(bounds.0, bounds.1)
52            }
53        }
54    };
55}
56
57u_range_op!(u8, u8);
58u_range_op!(u16, u16);
59u_range_op!(u32, u32);
60u_range_op!(u64, u64);
61u_range_op!(u128, u128);
62u_range_op!(usize, usize);
63i_range_op!(i8, u8);
64i_range_op!(i16, u16);
65i_range_op!(i32, u32);
66i_range_op!(i64, u64);
67i_range_op!(i128, u128);
68i_range_op!(isize, usize);
69
70impl RangeOp for f32 {
71    type Step = f32;
72
73    #[inline(always)]
74    fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
75        (self + delta).clamp(bounds.0, bounds.1)
76    }
77
78    #[inline(always)]
79    fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
80        (self - delta).clamp(bounds.0, bounds.1)
81    }
82}
83
84impl RangeOp for f64 {
85    type Step = f64;
86
87    #[inline(always)]
88    fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
89        (self + delta).clamp(bounds.0, bounds.1)
90    }
91
92    #[inline(always)]
93    fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
94        (self - delta).clamp(bounds.0, bounds.1)
95    }
96}