option_operations/
sub.rs

1//! Traits for the substraction [`OptionOperations`].
2
3use core::ops::{Sub, SubAssign};
4
5use crate::{Error, OptionOperations};
6
7common_option_op!(Sub, sub, substraction);
8
9impl_for_ints!(OptionOverflowingSub, {
10    type Output = Self;
11    fn opt_overflowing_sub(self, rhs: Self) -> Option<(Self::Output, bool)> {
12        Some(self.overflowing_sub(rhs))
13    }
14});
15
16impl_for_ints!(OptionWrappingSub, {
17    type Output = Self;
18    fn opt_wrapping_sub(self, rhs: Self) -> Option<Self::Output> {
19        Some(self.wrapping_sub(rhs))
20    }
21});
22
23option_op_checked!(Sub, sub, substraction);
24
25impl_for_ints_and_duration!(OptionCheckedSub, {
26    type Output = Self;
27    fn opt_checked_sub(self, rhs: Self) -> Result<Option<Self::Output>, Error> {
28        self.checked_sub(rhs).ok_or(Error::Overflow).map(Some)
29    }
30});
31
32#[cfg(feature = "std")]
33impl OptionCheckedSub<std::time::Duration> for std::time::Instant {
34    type Output = Self;
35    fn opt_checked_sub(self, rhs: std::time::Duration) -> Result<Option<Self::Output>, Error> {
36        self.checked_sub(rhs).ok_or(Error::Overflow).map(Some)
37    }
38}
39
40#[cfg(feature = "std")]
41impl OptionCheckedSub<std::time::Duration> for std::time::SystemTime {
42    type Output = Self;
43    fn opt_checked_sub(self, rhs: std::time::Duration) -> Result<Option<Self::Output>, Error> {
44        self.checked_sub(rhs).ok_or(Error::Overflow).map(Some)
45    }
46}
47
48option_op_saturating!(Sub, sub, substraction);
49
50impl_for_ints_and_duration!(OptionSaturatingSub, {
51    type Output = Self;
52    fn opt_saturating_sub(self, rhs: Self) -> Option<Self::Output> {
53        Some(self.saturating_sub(rhs))
54    }
55});
56
57#[cfg(test)]
58mod test {
59    use super::*;
60    use crate::OptionOperations;
61    use core::ops::{Sub, SubAssign};
62
63    #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
64    struct MyInt(u64);
65
66    impl OptionOperations for MyInt {}
67
68    impl Sub<MyInt> for MyInt {
69        type Output = MyInt;
70
71        fn sub(self, rhs: MyInt) -> MyInt {
72            MyInt(self.0.sub(rhs.0))
73        }
74    }
75
76    impl Sub<u64> for MyInt {
77        type Output = MyInt;
78
79        fn sub(self, rhs: u64) -> MyInt {
80            MyInt(self.0.sub(rhs))
81        }
82    }
83
84    impl SubAssign<MyInt> for MyInt {
85        fn sub_assign(&mut self, rhs: MyInt) {
86            self.0.sub_assign(rhs.0)
87        }
88    }
89
90    impl SubAssign<u64> for MyInt {
91        fn sub_assign(&mut self, rhs: u64) {
92            self.0.sub_assign(rhs)
93        }
94    }
95
96    impl OptionCheckedSub for MyInt {
97        type Output = MyInt;
98        fn opt_checked_sub(self, rhs: MyInt) -> Result<Option<Self::Output>, Error> {
99            self.0.opt_checked_sub(rhs.0).map(|ok| ok.map(MyInt))
100        }
101    }
102
103    impl OptionCheckedSub<u64> for MyInt {
104        type Output = MyInt;
105        fn opt_checked_sub(self, rhs: u64) -> Result<Option<Self::Output>, Error> {
106            self.0.opt_checked_sub(rhs).map(|ok| ok.map(MyInt))
107        }
108    }
109
110    impl OptionSaturatingSub for MyInt {
111        type Output = MyInt;
112        fn opt_saturating_sub(self, rhs: MyInt) -> Option<Self::Output> {
113            self.0.opt_saturating_sub(rhs.0).map(MyInt)
114        }
115    }
116
117    impl OptionSaturatingSub<u64> for MyInt {
118        type Output = MyInt;
119        fn opt_saturating_sub(self, rhs: u64) -> Option<Self::Output> {
120            self.0.opt_saturating_sub(rhs).map(MyInt)
121        }
122    }
123
124    impl OptionOverflowingSub for MyInt {
125        type Output = MyInt;
126        fn opt_overflowing_sub(self, rhs: MyInt) -> Option<(Self::Output, bool)> {
127            self.0
128                .opt_overflowing_sub(rhs.0)
129                .map(|(val, flag)| (MyInt(val), flag))
130        }
131    }
132
133    impl OptionOverflowingSub<u64> for MyInt {
134        type Output = MyInt;
135        fn opt_overflowing_sub(self, rhs: u64) -> Option<(Self::Output, bool)> {
136            self.0
137                .opt_overflowing_sub(rhs)
138                .map(|(val, flag)| (MyInt(val), flag))
139        }
140    }
141
142    impl OptionWrappingSub for MyInt {
143        type Output = MyInt;
144        fn opt_wrapping_sub(self, rhs: MyInt) -> Option<Self::Output> {
145            self.0.opt_wrapping_sub(rhs.0).map(MyInt)
146        }
147    }
148
149    impl OptionWrappingSub<u64> for MyInt {
150        type Output = MyInt;
151        fn opt_wrapping_sub(self, rhs: u64) -> Option<Self::Output> {
152            self.0.opt_wrapping_sub(rhs).map(MyInt)
153        }
154    }
155
156    const MY_0: MyInt = MyInt(0);
157    const MY_1: MyInt = MyInt(1);
158    const MY_2: MyInt = MyInt(2);
159    const MY_3: MyInt = MyInt(3);
160    const MY_MAX: MyInt = MyInt(u64::MAX);
161    const SOME_0: Option<MyInt> = Some(MY_0);
162    const SOME_1: Option<MyInt> = Some(MY_1);
163    const SOME_2: Option<MyInt> = Some(MY_2);
164    const SOME_3: Option<MyInt> = Some(MY_3);
165    const SOME_MAX: Option<MyInt> = Some(MY_MAX);
166    const NONE: Option<MyInt> = None;
167
168    #[test]
169    fn sub_my() {
170        assert_eq!(MY_3.opt_sub(MY_1), SOME_2);
171        assert_eq!(SOME_3.opt_sub(MY_1), SOME_2);
172        assert_eq!(MY_3.opt_sub(SOME_1), SOME_2);
173        assert_eq!(MY_3.opt_sub(&SOME_1), SOME_2);
174        assert_eq!(MY_3.opt_sub(NONE), NONE);
175        assert_eq!(NONE.opt_sub(MY_3), NONE);
176    }
177
178    #[test]
179    fn sub_u64() {
180        assert_eq!(MY_3.opt_sub(1), SOME_2);
181        assert_eq!(MY_3.opt_sub(Some(1)), SOME_2);
182        assert_eq!(SOME_3.opt_sub(1), SOME_2);
183        assert_eq!(SOME_3.opt_sub(Some(1)), SOME_2);
184        assert_eq!(SOME_3.opt_sub(&Some(1)), SOME_2);
185        assert_eq!(MY_3.opt_sub(Option::<u64>::None), NONE);
186        assert_eq!(Option::<MyInt>::None.opt_sub(MY_0), NONE);
187    }
188
189    #[test]
190    fn sub_assign_my() {
191        let mut my = MY_3;
192        my.opt_sub_assign(MY_1);
193        assert_eq!(my, MY_2);
194
195        let mut some = SOME_3;
196        some.opt_sub_assign(MY_1);
197        assert_eq!(some, SOME_2);
198
199        let mut my = MY_3;
200        my.opt_sub_assign(SOME_1);
201        assert_eq!(my, MY_2);
202
203        let mut my = MY_3;
204        my.opt_sub_assign(&SOME_1);
205        assert_eq!(my, MY_2);
206
207        let mut my = MY_3;
208        my.opt_sub_assign(NONE);
209        assert_eq!(my, MY_3);
210
211        let mut some = SOME_3;
212        some.opt_sub_assign(SOME_1);
213        assert_eq!(some, SOME_2);
214
215        let mut some = SOME_3;
216        some.opt_sub_assign(&SOME_1);
217        assert_eq!(some, SOME_2);
218
219        let mut some = SOME_3;
220        some.opt_sub_assign(NONE);
221        assert_eq!(some, SOME_3);
222
223        let mut none = NONE;
224        none.opt_sub_assign(SOME_1);
225        assert_eq!(none, NONE);
226
227        let mut none = NONE;
228        none.opt_sub_assign(NONE);
229        assert_eq!(none, NONE);
230    }
231
232    #[test]
233    fn sub_assign_u64() {
234        let mut my = MY_3;
235        my.opt_sub_assign(1);
236        assert_eq!(my, MY_2);
237
238        let mut some = SOME_3;
239        some.opt_sub_assign(1);
240        assert_eq!(some, SOME_2);
241
242        let mut my = MY_3;
243        my.opt_sub_assign(Some(1));
244        assert_eq!(my, MY_2);
245
246        let mut my = MY_3;
247        my.opt_sub_assign(&Some(1));
248        assert_eq!(my, MY_2);
249
250        let mut some = SOME_3;
251        some.opt_sub_assign(Some(1));
252        assert_eq!(some, SOME_2);
253
254        let mut some = SOME_3;
255        some.opt_sub_assign(&Some(1));
256        assert_eq!(some, SOME_2);
257
258        let mut none = NONE;
259        none.opt_sub_assign(Some(1));
260        assert_eq!(none, NONE);
261    }
262
263    #[test]
264    fn checked_sub() {
265        assert_eq!(MY_3.opt_checked_sub(MY_1), Ok(SOME_2));
266        assert_eq!(MY_3.opt_checked_sub(SOME_1), Ok(SOME_2));
267        assert_eq!(MY_3.opt_checked_sub(&SOME_1), Ok(SOME_2));
268        assert_eq!(MY_0.opt_checked_sub(MY_1), Err(Error::Overflow));
269
270        assert_eq!(SOME_3.opt_checked_sub(MY_1), Ok(SOME_2));
271        assert_eq!(SOME_3.opt_checked_sub(SOME_1), Ok(SOME_2));
272        assert_eq!(SOME_3.opt_checked_sub(&SOME_1), Ok(SOME_2));
273
274        assert_eq!(SOME_0.opt_checked_sub(MY_1), Err(Error::Overflow));
275        assert_eq!(SOME_0.opt_checked_sub(1), Err(Error::Overflow));
276        assert_eq!(SOME_0.opt_checked_sub(Some(1)), Err(Error::Overflow));
277        assert_eq!(MY_0.opt_checked_sub(SOME_1), Err(Error::Overflow));
278        assert_eq!(MY_0.opt_checked_sub(NONE), Ok(None));
279        assert_eq!(NONE.opt_checked_sub(MY_0), Ok(None));
280    }
281
282    #[test]
283    fn saturating_sub() {
284        assert_eq!(MY_3.opt_saturating_sub(MY_1), SOME_2);
285        assert_eq!(MY_1.opt_saturating_sub(MY_2), SOME_0);
286        assert_eq!(SOME_1.opt_saturating_sub(MY_2), SOME_0);
287        assert_eq!(SOME_1.opt_saturating_sub(2), SOME_0);
288        assert_eq!(SOME_1.opt_saturating_sub(Some(2)), SOME_0);
289        assert_eq!(SOME_1.opt_saturating_sub(&Some(2)), SOME_0);
290        assert_eq!(MY_1.opt_saturating_sub(SOME_2), SOME_0);
291        assert_eq!(MY_1.opt_saturating_sub(&SOME_2), SOME_0);
292        assert_eq!(MY_1.opt_saturating_sub(NONE), NONE);
293        assert_eq!(NONE.opt_saturating_sub(MY_1), NONE);
294    }
295
296    #[test]
297    fn overflowing_sub() {
298        assert_eq!(MY_3.opt_overflowing_sub(MY_1), Some((MY_2, false)));
299        assert_eq!(MY_1.opt_overflowing_sub(MY_2), Some((MY_MAX, true)));
300        assert_eq!(SOME_1.opt_overflowing_sub(MY_2), Some((MY_MAX, true)));
301        assert_eq!(SOME_1.opt_overflowing_sub(2), Some((MY_MAX, true)));
302        assert_eq!(SOME_1.opt_overflowing_sub(Some(2)), Some((MY_MAX, true)));
303        assert_eq!(SOME_1.opt_overflowing_sub(&Some(2)), Some((MY_MAX, true)));
304        assert_eq!(MY_1.opt_overflowing_sub(SOME_2), Some((MY_MAX, true)));
305        assert_eq!(MY_1.opt_overflowing_sub(&SOME_2), Some((MY_MAX, true)));
306        assert_eq!(MY_1.opt_overflowing_sub(NONE), None);
307        assert_eq!(NONE.opt_overflowing_sub(MY_1), None);
308    }
309
310    #[test]
311    fn wrapping_sub() {
312        assert_eq!(MY_3.opt_wrapping_sub(MY_1), SOME_2);
313        assert_eq!(MY_1.opt_wrapping_sub(MY_2), SOME_MAX);
314        assert_eq!(SOME_1.opt_wrapping_sub(MY_2), SOME_MAX);
315        assert_eq!(SOME_1.opt_wrapping_sub(2), SOME_MAX);
316        assert_eq!(SOME_1.opt_wrapping_sub(Some(2)), SOME_MAX);
317        assert_eq!(SOME_1.opt_wrapping_sub(&Some(2)), SOME_MAX);
318        assert_eq!(MY_1.opt_wrapping_sub(SOME_2), SOME_MAX);
319        assert_eq!(MY_1.opt_wrapping_sub(&SOME_2), SOME_MAX);
320        assert_eq!(MY_1.opt_wrapping_sub(NONE), None);
321        assert_eq!(NONE.opt_wrapping_sub(MY_1), None);
322    }
323}