scsys_traits/ops/
incremental.rs

1/*
2   Appellation: incremental <traits>
3   Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use num_traits::One;
6
7/// [`Decrement`] defines an interface for decrementing a value.
8pub trait Decrement {
9    type Output;
10
11    fn dec(self) -> Self::Output;
12}
13/// [`DecrementRef`] is a trait describing the ability to decrement a value by reference.
14pub trait DecrementRef {
15    type Output;
16
17    fn dec_ref(&self) -> Self::Output;
18}
19/// [`DecrementMut`] is a trait describing the ability to decrement a value in place. It is
20/// similar to [`Decrement`], but it allows for mutable access to the value.
21///
22/// **note**: the automatic implementation of `DecrementMut` leverages the [`replace`](core::mem::replace)
23/// method to compute the next value, replacing and returning the previous value.
24pub trait DecrementMut {
25    type Output;
26
27    fn dec_mut(&mut self) -> Self::Output;
28}
29/// [`Increment`] defines an interface for incrementing a value.
30pub trait Increment {
31    type Output;
32
33    fn inc(self) -> Self::Output;
34}
35/// [`IncrementRef`] is similar to [`Increment`], but it allows for incrementing a value by
36/// reference.
37pub trait IncrementRef {
38    type Output;
39
40    fn inc_ref(&self) -> Self::Output;
41}
42/// [`IncrementMut`] is similar to [`Increment`], but it allows for incrementing a value in place.
43///
44/// **note**: the automatic implementation of `IncrementMut` leverages the [`replace`](core::mem::replace)
45/// method to compute the next value, replacing and returning the previous value.
46pub trait IncrementMut {
47    type Output;
48
49    fn inc_mut(&mut self) -> Self::Output;
50}
51
52/*
53 ******** implementations ********
54*/
55impl<S> Decrement for S
56where
57    S: One + core::ops::Sub<S, Output = S>,
58{
59    type Output = S;
60
61    fn dec(self) -> Self::Output {
62        self - S::one()
63    }
64}
65
66impl<S> DecrementMut for S
67where
68    S: One,
69    for<'a> &'a S: core::ops::Sub<S, Output = S>,
70{
71    type Output = S;
72
73    fn dec_mut(&mut self) -> Self::Output {
74        let next = &(*self) - S::one();
75        core::mem::replace(self, next)
76    }
77}
78
79impl<S> DecrementRef for S
80where
81    S: One,
82    for<'a> &'a S: core::ops::Sub<S, Output = S>,
83{
84    type Output = S;
85
86    fn dec_ref(&self) -> Self::Output {
87        self - S::one()
88    }
89}
90
91impl<S> Increment for S
92where
93    S: One + core::ops::Add<S, Output = S>,
94{
95    type Output = S;
96
97    fn inc(self) -> Self::Output {
98        self + S::one()
99    }
100}
101
102impl<S> IncrementMut for S
103where
104    S: One,
105    for<'a> &'a S: core::ops::Add<S, Output = S>,
106{
107    type Output = S;
108
109    fn inc_mut(&mut self) -> Self::Output {
110        let next = &(*self) + S::one();
111        core::mem::replace(self, next)
112    }
113}
114
115impl<S> IncrementRef for S
116where
117    S: One,
118    for<'a> &'a S: core::ops::Add<S, Output = S>,
119{
120    type Output = S;
121
122    fn inc_ref(&self) -> Self::Output {
123        self + S::one()
124    }
125}