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    const MY_0: MyInt = MyInt(0);
97    const MY_1: MyInt = MyInt(1);
98    const MY_2: MyInt = MyInt(2);
99    const MY_3: MyInt = MyInt(3);
100    const MY_MAX: MyInt = MyInt(u64::MAX);
101    const SOME_0: Option<MyInt> = Some(MY_0);
102    const SOME_1: Option<MyInt> = Some(MY_1);
103    const SOME_2: Option<MyInt> = Some(MY_2);
104    const SOME_3: Option<MyInt> = Some(MY_3);
105    const SOME_MAX: Option<MyInt> = Some(MY_MAX);
106    const NONE: Option<MyInt> = None;
107
108    #[test]
109    fn sub_my() {
110        assert_eq!(MY_3.opt_sub(MY_1), SOME_2);
111        assert_eq!(SOME_3.opt_sub(MY_1), SOME_2);
112        assert_eq!(MY_3.opt_sub(SOME_1), SOME_2);
113        assert_eq!(MY_3.opt_sub(&SOME_1), SOME_2);
114        assert_eq!(MY_3.opt_sub(NONE), NONE);
115        assert_eq!(NONE.opt_sub(MY_3), NONE);
116    }
117
118    #[test]
119    fn sub_u64() {
120        assert_eq!(MY_3.opt_sub(1), SOME_2);
121        assert_eq!(MY_3.opt_sub(Some(1)), SOME_2);
122        assert_eq!(SOME_3.opt_sub(1), SOME_2);
123        assert_eq!(SOME_3.opt_sub(Some(1)), SOME_2);
124        assert_eq!(SOME_3.opt_sub(&Some(1)), SOME_2);
125        assert_eq!(MY_3.opt_sub(Option::<u64>::None), NONE);
126        assert_eq!(Option::<MyInt>::None.opt_sub(MY_0), NONE);
127    }
128
129    #[test]
130    fn sub_assign_my() {
131        let mut my = MY_3;
132        my.opt_sub_assign(MY_1);
133        assert_eq!(my, MY_2);
134
135        let mut some = SOME_3;
136        some.opt_sub_assign(MY_1);
137        assert_eq!(some, SOME_2);
138
139        let mut my = MY_3;
140        my.opt_sub_assign(SOME_1);
141        assert_eq!(my, MY_2);
142
143        let mut my = MY_3;
144        my.opt_sub_assign(&SOME_1);
145        assert_eq!(my, MY_2);
146
147        let mut my = MY_3;
148        my.opt_sub_assign(NONE);
149        assert_eq!(my, MY_3);
150
151        let mut some = SOME_3;
152        some.opt_sub_assign(SOME_1);
153        assert_eq!(some, SOME_2);
154
155        let mut some = SOME_3;
156        some.opt_sub_assign(&SOME_1);
157        assert_eq!(some, SOME_2);
158
159        let mut some = SOME_3;
160        some.opt_sub_assign(NONE);
161        assert_eq!(some, SOME_3);
162
163        let mut none = NONE;
164        none.opt_sub_assign(SOME_1);
165        assert_eq!(none, NONE);
166
167        let mut none = NONE;
168        none.opt_sub_assign(NONE);
169        assert_eq!(none, NONE);
170    }
171
172    #[test]
173    fn sub_assign_u64() {
174        let mut my = MY_3;
175        my.opt_sub_assign(1);
176        assert_eq!(my, MY_2);
177
178        let mut some = SOME_3;
179        some.opt_sub_assign(1);
180        assert_eq!(some, SOME_2);
181
182        let mut my = MY_3;
183        my.opt_sub_assign(Some(1));
184        assert_eq!(my, MY_2);
185
186        let mut my = MY_3;
187        my.opt_sub_assign(&Some(1));
188        assert_eq!(my, MY_2);
189
190        let mut some = SOME_3;
191        some.opt_sub_assign(Some(1));
192        assert_eq!(some, SOME_2);
193
194        let mut some = SOME_3;
195        some.opt_sub_assign(&Some(1));
196        assert_eq!(some, SOME_2);
197
198        let mut none = NONE;
199        none.opt_sub_assign(Some(1));
200        assert_eq!(none, NONE);
201    }
202
203    #[test]
204    fn checked_sub() {
205        impl OptionCheckedSub for MyInt {
206            type Output = MyInt;
207            fn opt_checked_sub(self, rhs: MyInt) -> Result<Option<Self::Output>, Error> {
208                self.0.opt_checked_sub(rhs.0).map(|ok| ok.map(MyInt))
209            }
210        }
211
212        impl OptionCheckedSub<u64> for MyInt {
213            type Output = MyInt;
214            fn opt_checked_sub(self, rhs: u64) -> Result<Option<Self::Output>, Error> {
215                self.0.opt_checked_sub(rhs).map(|ok| ok.map(MyInt))
216            }
217        }
218
219        assert_eq!(MY_3.opt_checked_sub(MY_1), Ok(SOME_2));
220        assert_eq!(MY_3.opt_checked_sub(SOME_1), Ok(SOME_2));
221        assert_eq!(MY_3.opt_checked_sub(&SOME_1), Ok(SOME_2));
222        assert_eq!(MY_0.opt_checked_sub(MY_1), Err(Error::Overflow));
223
224        assert_eq!(SOME_3.opt_checked_sub(MY_1), Ok(SOME_2));
225        assert_eq!(SOME_3.opt_checked_sub(SOME_1), Ok(SOME_2));
226        assert_eq!(SOME_3.opt_checked_sub(&SOME_1), Ok(SOME_2));
227
228        assert_eq!(SOME_0.opt_checked_sub(MY_1), Err(Error::Overflow));
229        assert_eq!(SOME_0.opt_checked_sub(1), Err(Error::Overflow));
230        assert_eq!(SOME_0.opt_checked_sub(Some(1)), Err(Error::Overflow));
231        assert_eq!(MY_0.opt_checked_sub(SOME_1), Err(Error::Overflow));
232        assert_eq!(MY_0.opt_checked_sub(NONE), Ok(None));
233        assert_eq!(NONE.opt_checked_sub(MY_0), Ok(None));
234    }
235
236    #[test]
237    fn saturating_sub() {
238        impl OptionSaturatingSub for MyInt {
239            type Output = MyInt;
240            fn opt_saturating_sub(self, rhs: MyInt) -> Option<Self::Output> {
241                self.0.opt_saturating_sub(rhs.0).map(MyInt)
242            }
243        }
244
245        impl OptionSaturatingSub<u64> for MyInt {
246            type Output = MyInt;
247            fn opt_saturating_sub(self, rhs: u64) -> Option<Self::Output> {
248                self.0.opt_saturating_sub(rhs).map(MyInt)
249            }
250        }
251
252        assert_eq!(MY_3.opt_saturating_sub(MY_1), SOME_2);
253        assert_eq!(MY_1.opt_saturating_sub(MY_2), SOME_0);
254        assert_eq!(SOME_1.opt_saturating_sub(MY_2), SOME_0);
255        assert_eq!(SOME_1.opt_saturating_sub(2), SOME_0);
256        assert_eq!(SOME_1.opt_saturating_sub(Some(2)), SOME_0);
257        assert_eq!(SOME_1.opt_saturating_sub(&Some(2)), SOME_0);
258        assert_eq!(MY_1.opt_saturating_sub(SOME_2), SOME_0);
259        assert_eq!(MY_1.opt_saturating_sub(&SOME_2), SOME_0);
260        assert_eq!(MY_1.opt_saturating_sub(NONE), NONE);
261        assert_eq!(NONE.opt_saturating_sub(MY_1), NONE);
262    }
263
264    #[test]
265    fn overflowing_sub() {
266        impl OptionOverflowingSub for MyInt {
267            type Output = MyInt;
268            fn opt_overflowing_sub(self, rhs: MyInt) -> Option<(Self::Output, bool)> {
269                self.0
270                    .opt_overflowing_sub(rhs.0)
271                    .map(|(val, flag)| (MyInt(val), flag))
272            }
273        }
274
275        impl OptionOverflowingSub<u64> for MyInt {
276            type Output = MyInt;
277            fn opt_overflowing_sub(self, rhs: u64) -> Option<(Self::Output, bool)> {
278                self.0
279                    .opt_overflowing_sub(rhs)
280                    .map(|(val, flag)| (MyInt(val), flag))
281            }
282        }
283
284        assert_eq!(MY_3.opt_overflowing_sub(MY_1), Some((MY_2, false)));
285        assert_eq!(MY_1.opt_overflowing_sub(MY_2), Some((MY_MAX, true)));
286        assert_eq!(SOME_1.opt_overflowing_sub(MY_2), Some((MY_MAX, true)));
287        assert_eq!(SOME_1.opt_overflowing_sub(2), Some((MY_MAX, true)));
288        assert_eq!(SOME_1.opt_overflowing_sub(Some(2)), Some((MY_MAX, true)));
289        assert_eq!(SOME_1.opt_overflowing_sub(&Some(2)), Some((MY_MAX, true)));
290        assert_eq!(MY_1.opt_overflowing_sub(SOME_2), Some((MY_MAX, true)));
291        assert_eq!(MY_1.opt_overflowing_sub(&SOME_2), Some((MY_MAX, true)));
292        assert_eq!(MY_1.opt_overflowing_sub(NONE), None);
293        assert_eq!(NONE.opt_overflowing_sub(MY_1), None);
294    }
295
296    #[test]
297    fn wrapping_sub() {
298        impl OptionWrappingSub for MyInt {
299            type Output = MyInt;
300            fn opt_wrapping_sub(self, rhs: MyInt) -> Option<Self::Output> {
301                self.0.opt_wrapping_sub(rhs.0).map(MyInt)
302            }
303        }
304
305        impl OptionWrappingSub<u64> for MyInt {
306            type Output = MyInt;
307            fn opt_wrapping_sub(self, rhs: u64) -> Option<Self::Output> {
308                self.0.opt_wrapping_sub(rhs).map(MyInt)
309            }
310        }
311
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}