1use core::ops::{Mul, MulAssign};
4
5use crate::{Error, OptionOperations};
6
7common_option_op!(Mul, mul, multiplication);
8
9impl_for_ints!(OptionOverflowingMul, {
10 type Output = Self;
11 fn opt_overflowing_mul(self, rhs: Self) -> Option<(Self::Output, bool)> {
12 Some(self.overflowing_mul(rhs))
13 }
14});
15
16impl_for_ints!(OptionWrappingMul, {
17 type Output = Self;
18 fn opt_wrapping_mul(self, rhs: Self) -> Option<Self::Output> {
19 Some(self.wrapping_mul(rhs))
20 }
21});
22
23option_op_checked!(Mul, mul, multiplication);
24
25impl_for_ints!(OptionCheckedMul, {
26 type Output = Self;
27 fn opt_checked_mul(self, rhs: Self) -> Result<Option<Self::Output>, Error> {
28 self.checked_mul(rhs).ok_or(Error::Overflow).map(Some)
29 }
30});
31
32impl OptionCheckedMul<u32> for core::time::Duration {
33 type Output = Self;
34 fn opt_checked_mul(self, rhs: u32) -> Result<Option<Self::Output>, Error> {
35 self.checked_mul(rhs).ok_or(Error::Overflow).map(Some)
36 }
37}
38
39option_op_saturating!(Mul, mul, multiplication);
40
41impl_for_ints!(OptionSaturatingMul, {
42 type Output = Self;
43 fn opt_saturating_mul(self, rhs: Self) -> Option<Self::Output> {
44 Some(self.saturating_mul(rhs))
45 }
46});
47
48impl OptionSaturatingMul<u32> for core::time::Duration {
49 type Output = Self;
50 fn opt_saturating_mul(self, rhs: u32) -> Option<Self::Output> {
51 Some(self.saturating_mul(rhs))
52 }
53}
54
55#[cfg(test)]
56mod test {
57 use super::*;
58 use crate::OptionOperations;
59 use core::ops::{Mul, MulAssign};
60
61 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
62 struct MyInt(u64);
63
64 impl OptionOperations for MyInt {}
65
66 impl Mul<MyInt> for MyInt {
67 type Output = MyInt;
68
69 fn mul(self, rhs: MyInt) -> MyInt {
70 MyInt(self.0.mul(rhs.0))
71 }
72 }
73
74 impl Mul<u64> for MyInt {
75 type Output = MyInt;
76
77 fn mul(self, rhs: u64) -> MyInt {
78 MyInt(self.0.mul(rhs))
79 }
80 }
81
82 impl MulAssign<MyInt> for MyInt {
83 fn mul_assign(&mut self, rhs: MyInt) {
84 self.0.mul_assign(rhs.0)
85 }
86 }
87
88 impl MulAssign<u64> for MyInt {
89 fn mul_assign(&mut self, rhs: u64) {
90 self.0.mul_assign(rhs)
91 }
92 }
93
94 impl OptionCheckedMul for MyInt {
95 type Output = MyInt;
96 fn opt_checked_mul(self, rhs: MyInt) -> Result<Option<Self::Output>, Error> {
97 self.0.opt_checked_mul(rhs.0).map(|ok| ok.map(MyInt))
98 }
99 }
100
101 impl OptionCheckedMul<u64> for MyInt {
102 type Output = MyInt;
103 fn opt_checked_mul(self, rhs: u64) -> Result<Option<Self::Output>, Error> {
104 self.0.opt_checked_mul(rhs).map(|ok| ok.map(MyInt))
105 }
106 }
107
108 impl OptionSaturatingMul for MyInt {
109 type Output = MyInt;
110 fn opt_saturating_mul(self, rhs: MyInt) -> Option<Self::Output> {
111 self.0.opt_saturating_mul(rhs.0).map(MyInt)
112 }
113 }
114
115 impl OptionSaturatingMul<u64> for MyInt {
116 type Output = MyInt;
117 fn opt_saturating_mul(self, rhs: u64) -> Option<Self::Output> {
118 self.0.opt_saturating_mul(rhs).map(MyInt)
119 }
120 }
121
122 impl OptionOverflowingMul for MyInt {
123 type Output = MyInt;
124 fn opt_overflowing_mul(self, rhs: MyInt) -> Option<(Self::Output, bool)> {
125 self.0
126 .opt_overflowing_mul(rhs.0)
127 .map(|(val, flag)| (MyInt(val), flag))
128 }
129 }
130
131 impl OptionOverflowingMul<u64> for MyInt {
132 type Output = MyInt;
133 fn opt_overflowing_mul(self, rhs: u64) -> Option<(Self::Output, bool)> {
134 self.0
135 .opt_overflowing_mul(rhs)
136 .map(|(val, flag)| (MyInt(val), flag))
137 }
138 }
139
140 impl OptionWrappingMul for MyInt {
141 type Output = MyInt;
142 fn opt_wrapping_mul(self, rhs: MyInt) -> Option<Self::Output> {
143 self.0.opt_wrapping_mul(rhs.0).map(MyInt)
144 }
145 }
146
147 impl OptionWrappingMul<u64> for MyInt {
148 type Output = MyInt;
149 fn opt_wrapping_mul(self, rhs: u64) -> Option<Self::Output> {
150 self.0.opt_wrapping_mul(rhs).map(MyInt)
151 }
152 }
153
154 const MY_0: MyInt = MyInt(0);
155 const MY_1: MyInt = MyInt(1);
156 const MY_2: MyInt = MyInt(2);
157 const MY_5: MyInt = MyInt(5);
158 const MY_10: MyInt = MyInt(10);
159 const MY_HALF_MAX: MyInt = MyInt(u64::MAX / 2);
160 const MY_MAX_MINUS_1: MyInt = MyInt(u64::MAX - 1);
161 const MY_MAX: MyInt = MyInt(u64::MAX);
163 const SOME_0: Option<MyInt> = Some(MY_0);
164 const SOME_1: Option<MyInt> = Some(MY_1);
165 const SOME_2: Option<MyInt> = Some(MY_2);
166 const SOME_5: Option<MyInt> = Some(MY_5);
167 const SOME_10: Option<MyInt> = Some(MY_10);
168 const SOME_HALF_MAX: Option<MyInt> = Some(MY_HALF_MAX);
169 const SOME_MAX_MINUS_1: Option<MyInt> = Some(MY_MAX_MINUS_1);
170 const SOME_MAX: Option<MyInt> = Some(MY_MAX);
171 const NONE: Option<MyInt> = None;
172
173 #[test]
174 fn mul_my() {
175 assert_eq!(MY_1.opt_mul(MY_5), SOME_5);
176 assert_eq!(SOME_2.opt_mul(MY_5), SOME_10);
177 assert_eq!(MY_0.opt_mul(SOME_1), SOME_0);
178 assert_eq!(MY_HALF_MAX.opt_mul(&SOME_2), SOME_MAX_MINUS_1);
180 assert_eq!(MY_1.opt_mul(NONE), NONE);
181 assert_eq!(NONE.opt_mul(MY_1), NONE);
182 }
183
184 #[test]
185 fn mul_u64() {
186 assert_eq!(MY_1.opt_mul(5), SOME_5);
187 assert_eq!(SOME_2.opt_mul(5), SOME_10);
188 assert_eq!(MY_0.opt_mul(Some(1)), SOME_0);
189 assert_eq!(MY_HALF_MAX.opt_mul(Some(2)), SOME_MAX_MINUS_1);
191 assert_eq!(MY_1.opt_mul(Option::<u64>::None), NONE);
192 assert_eq!(Option::<MyInt>::None.opt_mul(MY_1), NONE);
193 }
194
195 #[test]
196 fn mul_assign_my() {
197 let mut my = MY_1;
198 my.opt_mul_assign(MY_5);
199 assert_eq!(my, MY_5);
200
201 let mut some = SOME_2;
202 some.opt_mul_assign(MY_5);
203 assert_eq!(some, SOME_10);
204
205 let mut my = MY_0;
206 my.opt_mul_assign(SOME_1);
207 assert_eq!(my, MY_0);
208
209 let mut my = MY_HALF_MAX;
211 my.opt_mul_assign(&SOME_2);
212 assert_eq!(my, MY_MAX_MINUS_1);
213
214 let mut my = MY_1;
215 my.opt_mul_assign(NONE);
216 assert_eq!(my, MY_1);
217
218 let mut some = SOME_1;
219 some.opt_mul_assign(SOME_2);
220 assert_eq!(some, SOME_2);
221
222 let mut some = SOME_5;
223 some.opt_mul_assign(&SOME_2);
224 assert_eq!(some, SOME_10);
225
226 let mut some = SOME_1;
227 some.opt_mul_assign(NONE);
228 assert_eq!(some, SOME_1);
229
230 let mut none = NONE;
231 none.opt_mul_assign(SOME_1);
232 assert_eq!(none, NONE);
233
234 let mut none = NONE;
235 none.opt_mul_assign(NONE);
236 assert_eq!(none, NONE);
237 }
238
239 #[test]
240 fn mul_assign_u64() {
241 let mut my = MY_1;
242 my.opt_mul_assign(5);
243 assert_eq!(my, MY_5);
244
245 let mut some = SOME_2;
246 some.opt_mul_assign(5);
247 assert_eq!(some, SOME_10);
248
249 let mut my = MY_0;
250 my.opt_mul_assign(1);
251 assert_eq!(my, MY_0);
252
253 let mut my = MY_HALF_MAX;
255 my.opt_mul_assign(2);
256 assert_eq!(my, MY_MAX_MINUS_1);
257
258 let mut my = MY_1;
259 my.opt_mul_assign(Option::<u64>::None);
260 assert_eq!(my, MY_1);
261
262 let mut some = SOME_1;
263 some.opt_mul_assign(2);
264 assert_eq!(some, SOME_2);
265
266 let mut some = SOME_1;
267 some.opt_mul_assign(Option::<u64>::None);
268 assert_eq!(some, SOME_1);
269
270 let mut none = NONE;
271 none.opt_mul_assign(1);
272 assert_eq!(none, NONE);
273
274 let mut none = NONE;
275 none.opt_mul_assign(Option::<u64>::None);
276 assert_eq!(none, NONE);
277 }
278
279 #[test]
280 fn checked_mul() {
281 assert_eq!(MY_1.opt_checked_mul(MY_2), Ok(SOME_2));
282 assert_eq!(MY_2.opt_checked_mul(SOME_5), Ok(SOME_10));
283 assert_eq!(MY_1.opt_checked_mul(&SOME_0), Ok(SOME_0));
284 assert_eq!(MY_HALF_MAX.opt_checked_mul(MY_2), Ok(SOME_MAX_MINUS_1));
285 assert_eq!(MY_HALF_MAX.opt_checked_mul(MY_5), Err(Error::Overflow));
286
287 assert_eq!(SOME_1.opt_checked_mul(MY_2), Ok(SOME_2));
288 assert_eq!(SOME_2.opt_checked_mul(SOME_5), Ok(SOME_10));
289 assert_eq!(SOME_1.opt_checked_mul(&SOME_0), Ok(SOME_0));
290
291 assert_eq!(SOME_HALF_MAX.opt_checked_mul(MY_2), Ok(SOME_MAX_MINUS_1));
292 assert_eq!(SOME_HALF_MAX.opt_checked_mul(MY_5), Err(Error::Overflow));
293 assert_eq!(SOME_MAX.opt_checked_mul(2), Err(Error::Overflow));
294 assert_eq!(SOME_HALF_MAX.opt_checked_mul(Some(5)), Err(Error::Overflow));
295 assert_eq!(SOME_MAX.opt_checked_mul(SOME_2), Err(Error::Overflow));
296 assert_eq!(MY_MAX.opt_checked_mul(NONE), Ok(None));
297 assert_eq!(NONE.opt_checked_mul(SOME_MAX), Ok(None));
298 }
299
300 #[test]
301 fn saturating_mul() {
302 assert_eq!(MY_1.opt_saturating_mul(MY_2), SOME_2);
303 assert_eq!(MY_0.opt_saturating_mul(MY_2), SOME_0);
304 assert_eq!(MY_MAX.opt_saturating_mul(MY_2), SOME_MAX);
305 assert_eq!(SOME_MAX.opt_saturating_mul(MY_2), SOME_MAX);
306 assert_eq!(SOME_MAX.opt_saturating_mul(2), SOME_MAX);
307 assert_eq!(SOME_MAX.opt_saturating_mul(Some(2)), SOME_MAX);
308 assert_eq!(SOME_MAX.opt_saturating_mul(&Some(2)), SOME_MAX);
309 assert_eq!(MY_2.opt_saturating_mul(SOME_MAX), SOME_MAX);
310 assert_eq!(MY_2.opt_saturating_mul(&SOME_MAX), SOME_MAX);
311 assert_eq!(MY_MAX.opt_saturating_mul(NONE), NONE);
312 assert_eq!(NONE.opt_saturating_mul(SOME_MAX), NONE);
313 }
314
315 #[test]
316 fn overflowing_mul() {
317 assert_eq!(MY_1.opt_overflowing_mul(MY_2), Some((MY_2, false)));
318 assert_eq!(MY_1.opt_overflowing_mul(MY_0), Some((MY_0, false)));
319 assert_eq!(
320 MY_MAX.opt_overflowing_mul(MY_2),
321 Some((MY_MAX_MINUS_1, true))
322 );
323 assert_eq!(
324 SOME_MAX.opt_overflowing_mul(MY_2),
325 Some((MY_MAX_MINUS_1, true))
326 );
327 assert_eq!(
328 SOME_MAX.opt_overflowing_mul(2),
329 Some((MY_MAX_MINUS_1, true))
330 );
331 assert_eq!(
332 SOME_MAX.opt_overflowing_mul(Some(2)),
333 Some((MY_MAX_MINUS_1, true))
334 );
335 assert_eq!(
336 SOME_MAX.opt_overflowing_mul(&Some(2)),
337 Some((MY_MAX_MINUS_1, true))
338 );
339 assert_eq!(
340 MY_2.opt_overflowing_mul(SOME_MAX),
341 Some((MY_MAX_MINUS_1, true))
342 );
343 assert_eq!(
344 MY_2.opt_overflowing_mul(&SOME_MAX),
345 Some((MY_MAX_MINUS_1, true))
346 );
347 assert_eq!(MY_MAX.opt_overflowing_mul(NONE), None);
348 assert_eq!(NONE.opt_overflowing_mul(SOME_MAX), None);
349 }
350
351 #[test]
352 fn wrapping_mul() {
353 assert_eq!(MY_1.opt_wrapping_mul(MY_2), SOME_2);
354 assert_eq!(MY_1.opt_wrapping_mul(MY_0), SOME_0);
355 assert_eq!(MY_MAX.opt_wrapping_mul(MY_2), SOME_MAX_MINUS_1);
356 assert_eq!(SOME_MAX.opt_wrapping_mul(MY_2), SOME_MAX_MINUS_1);
357 assert_eq!(SOME_MAX.opt_wrapping_mul(2), SOME_MAX_MINUS_1);
358 assert_eq!(SOME_MAX.opt_wrapping_mul(Some(2)), SOME_MAX_MINUS_1);
359 assert_eq!(SOME_MAX.opt_wrapping_mul(&Some(2)), SOME_MAX_MINUS_1);
360 assert_eq!(MY_2.opt_wrapping_mul(SOME_MAX), SOME_MAX_MINUS_1);
361 assert_eq!(MY_2.opt_wrapping_mul(&SOME_MAX), SOME_MAX_MINUS_1);
362 assert_eq!(MY_MAX.opt_wrapping_mul(NONE), None);
363 assert_eq!(NONE.opt_wrapping_mul(SOME_MAX), None);
364 }
365}