1use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
65
66use super::int_operand::IntOperand;
67use super::{
68 impl_binop_uuid_uuid, impl_int_op_uuid_commutative, impl_int_op_uuid_noncommutative,
69 impl_ref_lhs_uuid, impl_uuid_op_int,
70};
71use crate::UUID;
72
73impl_binop_uuid_uuid!(Add, add, AddAssign, add_assign, u128::wrapping_add);
78impl_binop_uuid_uuid!(Sub, sub, SubAssign, sub_assign, u128::wrapping_sub);
79impl_binop_uuid_uuid!(Mul, mul, MulAssign, mul_assign, u128::wrapping_mul);
80impl_binop_uuid_uuid!(Div, div, DivAssign, div_assign, u128::div);
81impl_binop_uuid_uuid!(Rem, rem, RemAssign, rem_assign, u128::rem);
82
83impl_ref_lhs_uuid!(Add, add);
84impl_ref_lhs_uuid!(Sub, sub);
85impl_ref_lhs_uuid!(Mul, mul);
86impl_ref_lhs_uuid!(Div, div);
87impl_ref_lhs_uuid!(Rem, rem);
88
89impl_uuid_op_int!(Add, add, AddAssign, add_assign, u128::wrapping_add);
94impl_uuid_op_int!(Sub, sub, SubAssign, sub_assign, u128::wrapping_sub);
95impl_uuid_op_int!(Mul, mul, MulAssign, mul_assign, u128::wrapping_mul);
96impl_uuid_op_int!(Div, div, DivAssign, div_assign, u128::div);
97impl_uuid_op_int!(Rem, rem, RemAssign, rem_assign, u128::rem);
98
99impl_int_op_uuid_commutative!(
105 Add, add, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
106);
107impl_int_op_uuid_commutative!(
108 Mul, mul, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
109);
110
111impl_int_op_uuid_noncommutative!(
113 Sub,
114 sub,
115 u128::wrapping_sub,
116 u8,
117 u16,
118 u32,
119 u64,
120 u128,
121 usize,
122 i8,
123 i16,
124 i32,
125 i64,
126 i128,
127 isize
128);
129impl_int_op_uuid_noncommutative!(
130 Div,
131 div,
132 u128::div,
133 u8,
134 u16,
135 u32,
136 u64,
137 u128,
138 usize,
139 i8,
140 i16,
141 i32,
142 i64,
143 i128,
144 isize
145);
146impl_int_op_uuid_noncommutative!(
147 Rem,
148 rem,
149 u128::rem,
150 u8,
151 u16,
152 u32,
153 u64,
154 u128,
155 usize,
156 i8,
157 i16,
158 i32,
159 i64,
160 i128,
161 isize
162);
163
164#[cfg(test)]
169mod tests {
170 #![allow(clippy::op_ref)]
171
172 use super::*;
173
174 #[test]
179 fn add_uuid_uuid() {
180 let a = UUID::from(100u128);
181 let b = UUID::from(50u128);
182 assert_eq!(u128::from(a + b), 150);
183 }
184
185 #[test]
186 fn add_uuid_ref_uuid() {
187 let a = UUID::from(100u128);
188 let b = UUID::from(50u128);
189 assert_eq!(u128::from(a + &b), 150);
190 }
191
192 #[test]
193 fn add_ref_uuid_uuid() {
194 let a = UUID::from(100u128);
195 let b = UUID::from(50u128);
196 assert_eq!(u128::from(&a + b), 150);
197 }
198
199 #[test]
200 fn add_ref_uuid_ref_uuid() {
201 let a = UUID::from(100u128);
202 let b = UUID::from(50u128);
203 assert_eq!(u128::from(&a + &b), 150);
204 }
205
206 #[test]
207 fn add_uuid_int() {
208 let uuid = UUID::from(100u128);
209 assert_eq!(u128::from(uuid + 50u8), 150);
210 assert_eq!(u128::from(uuid + 50u16), 150);
211 assert_eq!(u128::from(uuid + 50u32), 150);
212 assert_eq!(u128::from(uuid + 50u64), 150);
213 assert_eq!(u128::from(uuid + 50u128), 150);
214 assert_eq!(u128::from(uuid + 50usize), 150);
215 assert_eq!(u128::from(uuid + 50i8), 150);
216 assert_eq!(u128::from(uuid + 50i16), 150);
217 assert_eq!(u128::from(uuid + 50i32), 150);
218 assert_eq!(u128::from(uuid + 50i64), 150);
219 assert_eq!(u128::from(uuid + 50i128), 150);
220 assert_eq!(u128::from(uuid + 50isize), 150);
221 }
222
223 #[test]
224 fn add_int_uuid() {
225 let uuid = UUID::from(100u128);
226 assert_eq!(u128::from(50u8 + uuid), 150);
227 assert_eq!(u128::from(50u16 + uuid), 150);
228 assert_eq!(u128::from(50u32 + uuid), 150);
229 assert_eq!(u128::from(50u64 + uuid), 150);
230 assert_eq!(u128::from(50u128 + uuid), 150);
231 assert_eq!(u128::from(50usize + uuid), 150);
232 }
233
234 #[test]
235 fn add_int_ref_uuid() {
236 let uuid = UUID::from(100u128);
237 assert_eq!(u128::from(50u32 + &uuid), 150);
238 }
239
240 #[test]
241 fn add_ref_int_uuid() {
242 let uuid = UUID::from(100u128);
243 let n = 50u32;
244 assert_eq!(u128::from(&n + uuid), 150);
245 }
246
247 #[test]
248 fn add_ref_int_ref_uuid() {
249 let uuid = UUID::from(100u128);
250 let n = 50u32;
251 assert_eq!(u128::from(&n + &uuid), 150);
252 }
253
254 #[test]
255 fn add_wraps_on_overflow() {
256 let max = UUID::max();
257 assert_eq!(max + 1u32, UUID::nil());
258 assert_eq!(max + 2u32, UUID::from(1u128));
259 }
260
261 #[test]
262 fn add_assign_uuid() {
263 let mut uuid = UUID::from(100u128);
264 uuid += UUID::from(50u128);
265 assert_eq!(u128::from(uuid), 150);
266 }
267
268 #[test]
269 fn add_assign_ref_uuid() {
270 let mut uuid = UUID::from(100u128);
271 let other = UUID::from(50u128);
272 uuid += &other;
273 assert_eq!(u128::from(uuid), 150);
274 }
275
276 #[test]
277 fn add_assign_int() {
278 let mut uuid = UUID::from(100u128);
279 uuid += 50u32;
280 assert_eq!(u128::from(uuid), 150);
281 }
282
283 #[test]
288 fn sub_uuid_uuid() {
289 let a = UUID::from(100u128);
290 let b = UUID::from(30u128);
291 assert_eq!(u128::from(a - b), 70);
292 }
293
294 #[test]
295 fn sub_uuid_int() {
296 let uuid = UUID::from(100u128);
297 assert_eq!(u128::from(uuid - 30u32), 70);
298 }
299
300 #[test]
301 fn sub_int_uuid() {
302 let uuid = UUID::from(30u128);
303 assert_eq!(u128::from(100u32 - uuid), 70);
304 }
305
306 #[test]
307 fn sub_wraps_on_underflow() {
308 let zero = UUID::nil();
309 assert_eq!(zero - 1u32, UUID::max());
310 assert_eq!(zero - 2u32, UUID::from(u128::MAX - 1));
311 }
312
313 #[test]
314 fn sub_noncommutative() {
315 let a = UUID::from(100u128);
316 assert_eq!(u128::from(a - 30u32), 70);
318 assert_eq!(u128::from(30u32 - a), u128::MAX - 69); }
320
321 #[test]
322 fn sub_assign() {
323 let mut uuid = UUID::from(100u128);
324 uuid -= 30u32;
325 assert_eq!(u128::from(uuid), 70);
326 }
327
328 #[test]
333 fn mul_uuid_uuid() {
334 let a = UUID::from(10u128);
335 let b = UUID::from(20u128);
336 assert_eq!(u128::from(a * b), 200);
337 }
338
339 #[test]
340 fn mul_uuid_int() {
341 let uuid = UUID::from(10u128);
342 assert_eq!(u128::from(uuid * 20u32), 200);
343 }
344
345 #[test]
346 fn mul_int_uuid() {
347 let uuid = UUID::from(10u128);
348 assert_eq!(u128::from(20u32 * uuid), 200);
349 }
350
351 #[test]
352 fn mul_wraps_on_overflow() {
353 let large = UUID::from(u128::MAX / 2 + 1);
354 let result = large * 2u32;
355 assert_eq!(u128::from(result), 0);
357 }
358
359 #[test]
360 fn mul_assign() {
361 let mut uuid = UUID::from(10u128);
362 uuid *= 20u32;
363 assert_eq!(u128::from(uuid), 200);
364 }
365
366 #[test]
371 fn div_uuid_uuid() {
372 let a = UUID::from(100u128);
373 let b = UUID::from(10u128);
374 assert_eq!(u128::from(a / b), 10);
375 }
376
377 #[test]
378 fn div_uuid_int() {
379 let uuid = UUID::from(100u128);
380 assert_eq!(u128::from(uuid / 10u32), 10);
381 }
382
383 #[test]
384 fn div_int_uuid() {
385 let uuid = UUID::from(10u128);
386 assert_eq!(u128::from(100u32 / uuid), 10);
387 }
388
389 #[test]
390 fn div_truncates() {
391 let uuid = UUID::from(10u128);
392 assert_eq!(u128::from(uuid / 3u32), 3); }
394
395 #[test]
396 fn div_assign() {
397 let mut uuid = UUID::from(100u128);
398 uuid /= 10u32;
399 assert_eq!(u128::from(uuid), 10);
400 }
401
402 #[test]
403 #[should_panic(expected = "attempt to divide by zero")]
404 fn div_by_zero_panics() {
405 let uuid = UUID::from(100u128);
406 let _ = uuid / 0u32;
407 }
408
409 #[test]
414 fn rem_uuid_uuid() {
415 let a = UUID::from(100u128);
416 let b = UUID::from(30u128);
417 assert_eq!(u128::from(a % b), 10);
418 }
419
420 #[test]
421 fn rem_uuid_int() {
422 let uuid = UUID::from(100u128);
423 assert_eq!(u128::from(uuid % 30u32), 10);
424 }
425
426 #[test]
427 fn rem_int_uuid() {
428 let uuid = UUID::from(30u128);
429 assert_eq!(u128::from(100u32 % uuid), 10);
430 }
431
432 #[test]
433 fn rem_assign() {
434 let mut uuid = UUID::from(100u128);
435 uuid %= 30u32;
436 assert_eq!(u128::from(uuid), 10);
437 }
438
439 #[test]
440 #[should_panic(expected = "attempt to calculate the remainder with a divisor of zero")]
441 fn rem_by_zero_panics() {
442 let uuid = UUID::from(100u128);
443 let _ = uuid % 0u32;
444 }
445
446 #[test]
451 fn all_reference_variants_add() {
452 let a = UUID::from(100u128);
453 let b = UUID::from(50u128);
454 let n = 50u32;
455
456 assert_eq!(a + b, UUID::from(150u128));
458 assert_eq!(a + &b, UUID::from(150u128));
459 assert_eq!(&a + b, UUID::from(150u128));
460 assert_eq!(&a + &b, UUID::from(150u128));
461
462 assert_eq!(a + n, UUID::from(150u128));
464 assert_eq!(&a + n, UUID::from(150u128));
465 assert_eq!(a + &n, UUID::from(150u128));
466 assert_eq!(&a + &n, UUID::from(150u128));
467
468 assert_eq!(n + a, UUID::from(150u128));
470 assert_eq!(n + &a, UUID::from(150u128));
471 assert_eq!(&n + a, UUID::from(150u128));
472 assert_eq!(&n + &a, UUID::from(150u128));
473 }
474
475 #[test]
480 fn add_negative_int_wraps() {
481 let uuid = UUID::from(100u128);
482 let result = uuid + (-1i32);
485 assert_eq!(result, UUID::from(99u128));
486 }
487
488 #[test]
489 fn sub_negative_int() {
490 let uuid = UUID::from(100u128);
491 let result = uuid - (-1i32);
494 assert_eq!(result, UUID::from(101u128));
495 }
496
497 #[test]
502 fn add_zero_is_identity() {
503 let uuid = UUID::from(42u128);
504 assert_eq!(uuid + 0u32, uuid);
505 assert_eq!(uuid + UUID::nil(), uuid);
506 }
507
508 #[test]
509 fn sub_zero_is_identity() {
510 let uuid = UUID::from(42u128);
511 assert_eq!(uuid - 0u32, uuid);
512 assert_eq!(uuid - UUID::nil(), uuid);
513 }
514
515 #[test]
516 fn mul_one_is_identity() {
517 let uuid = UUID::from(42u128);
518 assert_eq!(uuid * 1u32, uuid);
519 assert_eq!(uuid * UUID::from(1u128), uuid);
520 }
521
522 #[test]
523 #[allow(clippy::erasing_op)]
524 fn mul_zero_is_zero() {
525 let uuid = UUID::from(42u128);
526 assert_eq!(uuid * 0u32, UUID::nil());
527 assert_eq!(uuid * UUID::nil(), UUID::nil());
528 }
529
530 #[test]
531 fn div_one_is_identity() {
532 let uuid = UUID::from(42u128);
533 assert_eq!(uuid / 1u32, uuid);
534 assert_eq!(uuid / UUID::from(1u128), uuid);
535 }
536
537 #[test]
538 fn div_self_is_one() {
539 let uuid = UUID::from(42u128);
540 assert_eq!(uuid / uuid, UUID::from(1u128));
541 }
542
543 #[test]
544 fn rem_self_is_zero() {
545 let uuid = UUID::from(42u128);
546 assert_eq!(uuid % uuid, UUID::nil());
547 }
548}