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