1 | //! Traits for the substraction [`OptionOperations`]. |
2 | |
3 | use core::ops::{Sub, SubAssign}; |
4 | |
5 | use crate::{Error, OptionOperations}; |
6 | |
7 | common_option_op!(Sub, sub, substraction); |
8 | |
9 | impl_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 | |
16 | impl_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 | |
23 | option_op_checked!(Sub, sub, substraction); |
24 | |
25 | impl_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" )] |
33 | impl 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(op:Some) |
37 | } |
38 | } |
39 | |
40 | #[cfg (feature = "std" )] |
41 | impl 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(op:Some) |
45 | } |
46 | } |
47 | |
48 | option_op_saturating!(Sub, sub, substraction); |
49 | |
50 | impl_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)] |
58 | mod 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 | } |
324 | |