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