1//! Traits for the multiplication [`OptionOperations`].
2
3use 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(op: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 const MY_0: MyInt = MyInt(0);
95 const MY_1: MyInt = MyInt(1);
96 const MY_2: MyInt = MyInt(2);
97 const MY_5: MyInt = MyInt(5);
98 const MY_10: MyInt = MyInt(10);
99 const MY_HALF_MAX: MyInt = MyInt(u64::MAX / 2);
100 const MY_MAX_MINUS_1: MyInt = MyInt(u64::MAX - 1);
101 // u64::MAX is an odd nb, so (u64::MAX / 2) * 2 == (u64::MAX - 1)
102 const MY_MAX: MyInt = MyInt(u64::MAX);
103 const SOME_0: Option<MyInt> = Some(MY_0);
104 const SOME_1: Option<MyInt> = Some(MY_1);
105 const SOME_2: Option<MyInt> = Some(MY_2);
106 const SOME_5: Option<MyInt> = Some(MY_5);
107 const SOME_10: Option<MyInt> = Some(MY_10);
108 const SOME_HALF_MAX: Option<MyInt> = Some(MY_HALF_MAX);
109 const SOME_MAX_MINUS_1: Option<MyInt> = Some(MY_MAX_MINUS_1);
110 const SOME_MAX: Option<MyInt> = Some(MY_MAX);
111 const NONE: Option<MyInt> = None;
112
113 #[test]
114 fn mul_my() {
115 assert_eq!(MY_1.opt_mul(MY_5), SOME_5);
116 assert_eq!(SOME_2.opt_mul(MY_5), SOME_10);
117 assert_eq!(MY_0.opt_mul(SOME_1), SOME_0);
118 // See comment in the const definitions
119 assert_eq!(MY_HALF_MAX.opt_mul(&SOME_2), SOME_MAX_MINUS_1);
120 assert_eq!(MY_1.opt_mul(NONE), NONE);
121 assert_eq!(NONE.opt_mul(MY_1), NONE);
122 }
123
124 #[test]
125 fn mul_u64() {
126 assert_eq!(MY_1.opt_mul(5), SOME_5);
127 assert_eq!(SOME_2.opt_mul(5), SOME_10);
128 assert_eq!(MY_0.opt_mul(Some(1)), SOME_0);
129 // See comment in the const definitions
130 assert_eq!(MY_HALF_MAX.opt_mul(Some(2)), SOME_MAX_MINUS_1);
131 assert_eq!(MY_1.opt_mul(Option::<u64>::None), NONE);
132 assert_eq!(Option::<MyInt>::None.opt_mul(MY_1), NONE);
133 }
134
135 #[test]
136 fn mul_assign_my() {
137 let mut my = MY_1;
138 my.opt_mul_assign(MY_5);
139 assert_eq!(my, MY_5);
140
141 let mut some = SOME_2;
142 some.opt_mul_assign(MY_5);
143 assert_eq!(some, SOME_10);
144
145 let mut my = MY_0;
146 my.opt_mul_assign(SOME_1);
147 assert_eq!(my, MY_0);
148
149 // See comment in the const definitions
150 let mut my = MY_HALF_MAX;
151 my.opt_mul_assign(&SOME_2);
152 assert_eq!(my, MY_MAX_MINUS_1);
153
154 let mut my = MY_1;
155 my.opt_mul_assign(NONE);
156 assert_eq!(my, MY_1);
157
158 let mut some = SOME_1;
159 some.opt_mul_assign(SOME_2);
160 assert_eq!(some, SOME_2);
161
162 let mut some = SOME_5;
163 some.opt_mul_assign(&SOME_2);
164 assert_eq!(some, SOME_10);
165
166 let mut some = SOME_1;
167 some.opt_mul_assign(NONE);
168 assert_eq!(some, SOME_1);
169
170 let mut none = NONE;
171 none.opt_mul_assign(SOME_1);
172 assert_eq!(none, NONE);
173
174 let mut none = NONE;
175 none.opt_mul_assign(NONE);
176 assert_eq!(none, NONE);
177 }
178
179 #[test]
180 fn mul_assign_u64() {
181 let mut my = MY_1;
182 my.opt_mul_assign(5);
183 assert_eq!(my, MY_5);
184
185 let mut some = SOME_2;
186 some.opt_mul_assign(5);
187 assert_eq!(some, SOME_10);
188
189 let mut my = MY_0;
190 my.opt_mul_assign(1);
191 assert_eq!(my, MY_0);
192
193 // See comment in the const definitions
194 let mut my = MY_HALF_MAX;
195 my.opt_mul_assign(2);
196 assert_eq!(my, MY_MAX_MINUS_1);
197
198 let mut my = MY_1;
199 my.opt_mul_assign(Option::<u64>::None);
200 assert_eq!(my, MY_1);
201
202 let mut some = SOME_1;
203 some.opt_mul_assign(2);
204 assert_eq!(some, SOME_2);
205
206 let mut some = SOME_1;
207 some.opt_mul_assign(Option::<u64>::None);
208 assert_eq!(some, SOME_1);
209
210 let mut none = NONE;
211 none.opt_mul_assign(1);
212 assert_eq!(none, NONE);
213
214 let mut none = NONE;
215 none.opt_mul_assign(Option::<u64>::None);
216 assert_eq!(none, NONE);
217 }
218
219 #[test]
220 fn checked_mul() {
221 impl OptionCheckedMul for MyInt {
222 type Output = MyInt;
223 fn opt_checked_mul(self, rhs: MyInt) -> Result<Option<Self::Output>, Error> {
224 self.0.opt_checked_mul(rhs.0).map(|ok| ok.map(MyInt))
225 }
226 }
227
228 impl OptionCheckedMul<u64> for MyInt {
229 type Output = MyInt;
230 fn opt_checked_mul(self, rhs: u64) -> Result<Option<Self::Output>, Error> {
231 self.0.opt_checked_mul(rhs).map(|ok| ok.map(MyInt))
232 }
233 }
234
235 assert_eq!(MY_1.opt_checked_mul(MY_2), Ok(SOME_2));
236 assert_eq!(MY_2.opt_checked_mul(SOME_5), Ok(SOME_10));
237 assert_eq!(MY_1.opt_checked_mul(&SOME_0), Ok(SOME_0));
238 assert_eq!(MY_HALF_MAX.opt_checked_mul(MY_2), Ok(SOME_MAX_MINUS_1));
239 assert_eq!(MY_HALF_MAX.opt_checked_mul(MY_5), Err(Error::Overflow));
240
241 assert_eq!(SOME_1.opt_checked_mul(MY_2), Ok(SOME_2));
242 assert_eq!(SOME_2.opt_checked_mul(SOME_5), Ok(SOME_10));
243 assert_eq!(SOME_1.opt_checked_mul(&SOME_0), Ok(SOME_0));
244
245 assert_eq!(SOME_HALF_MAX.opt_checked_mul(MY_2), Ok(SOME_MAX_MINUS_1));
246 assert_eq!(SOME_HALF_MAX.opt_checked_mul(MY_5), Err(Error::Overflow));
247 assert_eq!(SOME_MAX.opt_checked_mul(2), Err(Error::Overflow));
248 assert_eq!(SOME_HALF_MAX.opt_checked_mul(Some(5)), Err(Error::Overflow));
249 assert_eq!(SOME_MAX.opt_checked_mul(SOME_2), Err(Error::Overflow));
250 assert_eq!(MY_MAX.opt_checked_mul(NONE), Ok(None));
251 assert_eq!(NONE.opt_checked_mul(SOME_MAX), Ok(None));
252 }
253
254 #[test]
255 fn saturating_mul() {
256 impl OptionSaturatingMul for MyInt {
257 type Output = MyInt;
258 fn opt_saturating_mul(self, rhs: MyInt) -> Option<Self::Output> {
259 self.0.opt_saturating_mul(rhs.0).map(MyInt)
260 }
261 }
262
263 impl OptionSaturatingMul<u64> for MyInt {
264 type Output = MyInt;
265 fn opt_saturating_mul(self, rhs: u64) -> Option<Self::Output> {
266 self.0.opt_saturating_mul(rhs).map(MyInt)
267 }
268 }
269
270 assert_eq!(MY_1.opt_saturating_mul(MY_2), SOME_2);
271 assert_eq!(MY_0.opt_saturating_mul(MY_2), SOME_0);
272 assert_eq!(MY_MAX.opt_saturating_mul(MY_2), SOME_MAX);
273 assert_eq!(SOME_MAX.opt_saturating_mul(MY_2), SOME_MAX);
274 assert_eq!(SOME_MAX.opt_saturating_mul(2), SOME_MAX);
275 assert_eq!(SOME_MAX.opt_saturating_mul(Some(2)), SOME_MAX);
276 assert_eq!(SOME_MAX.opt_saturating_mul(&Some(2)), SOME_MAX);
277 assert_eq!(MY_2.opt_saturating_mul(SOME_MAX), SOME_MAX);
278 assert_eq!(MY_2.opt_saturating_mul(&SOME_MAX), SOME_MAX);
279 assert_eq!(MY_MAX.opt_saturating_mul(NONE), NONE);
280 assert_eq!(NONE.opt_saturating_mul(SOME_MAX), NONE);
281 }
282
283 #[test]
284 fn overflowing_mul() {
285 impl OptionOverflowingMul for MyInt {
286 type Output = MyInt;
287 fn opt_overflowing_mul(self, rhs: MyInt) -> Option<(Self::Output, bool)> {
288 self.0
289 .opt_overflowing_mul(rhs.0)
290 .map(|(val, flag)| (MyInt(val), flag))
291 }
292 }
293
294 impl OptionOverflowingMul<u64> for MyInt {
295 type Output = MyInt;
296 fn opt_overflowing_mul(self, rhs: u64) -> Option<(Self::Output, bool)> {
297 self.0
298 .opt_overflowing_mul(rhs)
299 .map(|(val, flag)| (MyInt(val), flag))
300 }
301 }
302
303 assert_eq!(MY_1.opt_overflowing_mul(MY_2), Some((MY_2, false)));
304 assert_eq!(MY_1.opt_overflowing_mul(MY_0), Some((MY_0, false)));
305 assert_eq!(
306 MY_MAX.opt_overflowing_mul(MY_2),
307 Some((MY_MAX_MINUS_1, true))
308 );
309 assert_eq!(
310 SOME_MAX.opt_overflowing_mul(MY_2),
311 Some((MY_MAX_MINUS_1, true))
312 );
313 assert_eq!(
314 SOME_MAX.opt_overflowing_mul(2),
315 Some((MY_MAX_MINUS_1, true))
316 );
317 assert_eq!(
318 SOME_MAX.opt_overflowing_mul(Some(2)),
319 Some((MY_MAX_MINUS_1, true))
320 );
321 assert_eq!(
322 SOME_MAX.opt_overflowing_mul(&Some(2)),
323 Some((MY_MAX_MINUS_1, true))
324 );
325 assert_eq!(
326 MY_2.opt_overflowing_mul(SOME_MAX),
327 Some((MY_MAX_MINUS_1, true))
328 );
329 assert_eq!(
330 MY_2.opt_overflowing_mul(&SOME_MAX),
331 Some((MY_MAX_MINUS_1, true))
332 );
333 assert_eq!(MY_MAX.opt_overflowing_mul(NONE), None);
334 assert_eq!(NONE.opt_overflowing_mul(SOME_MAX), None);
335 }
336
337 #[test]
338 fn wrapping_mul() {
339 impl OptionWrappingMul for MyInt {
340 type Output = MyInt;
341 fn opt_wrapping_mul(self, rhs: MyInt) -> Option<Self::Output> {
342 self.0.opt_wrapping_mul(rhs.0).map(MyInt)
343 }
344 }
345
346 impl OptionWrappingMul<u64> for MyInt {
347 type Output = MyInt;
348 fn opt_wrapping_mul(self, rhs: u64) -> Option<Self::Output> {
349 self.0.opt_wrapping_mul(rhs).map(MyInt)
350 }
351 }
352
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}
366