1use {
2 super::TryBinaryOperator,
3 crate::{
4 data::{NumericBinaryOperator, ValueError},
5 prelude::Value,
6 result::Result,
7 },
8 Value::*,
9 rust_decimal::prelude::Decimal,
10 std::cmp::Ordering,
11};
12
13impl PartialEq<Value> for Decimal {
14 fn eq(&self, other: &Value) -> bool {
15 match other {
16 I8(other) => *self == Decimal::from(*other),
17 I32(other) => *self == Decimal::from(*other),
18 I64(other) => *self == Decimal::from(*other),
19 I128(other) => *self == Decimal::from(*other),
20 U8(other) => *self == Decimal::from(*other),
21 U16(other) => *self == Decimal::from(*other),
22 U32(other) => *self == Decimal::from(*other),
23 U64(other) => *self == Decimal::from(*other),
24 U128(other) => *self == Decimal::from(*other),
25 F32(other) => Decimal::from_f32_retain(*other)
26 .map(|x| *self == x)
27 .unwrap_or(false),
28 F64(other) => Decimal::from_f64_retain(*other)
29 .map(|x| *self == x)
30 .unwrap_or(false),
31 Decimal(other) => *self == *other,
32 _ => false,
33 }
34 }
35}
36
37impl PartialOrd<Value> for Decimal {
38 fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
39 match *other {
40 I8(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
41 I32(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
42 I64(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
43 I128(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
44 U8(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
45 U16(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
46 U32(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
47 U64(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
48 U128(rhs) => self.partial_cmp(&(Decimal::from(rhs))),
49 F32(rhs) => Decimal::from_f32_retain(rhs)
50 .map(|x| self.partial_cmp(&x))
51 .unwrap_or(None),
52 F64(rhs) => Decimal::from_f64_retain(rhs)
53 .map(|x| self.partial_cmp(&x))
54 .unwrap_or(None),
55 Decimal(rhs) => self.partial_cmp(&rhs),
56 _ => None,
57 }
58 }
59}
60
61impl TryBinaryOperator for Decimal {
62 type Rhs = Value;
63
64 fn try_add(&self, rhs: &Self::Rhs) -> Result<Value> {
65 let lhs = *self;
66
67 match *rhs {
68 I8(rhs) => lhs
69 .checked_add(Decimal::from(rhs))
70 .ok_or_else(|| {
71 ValueError::BinaryOperationOverflow {
72 lhs: Decimal(lhs),
73 rhs: I8(rhs),
74 operator: NumericBinaryOperator::Add,
75 }
76 .into()
77 })
78 .map(Decimal),
79 I32(rhs) => lhs
80 .checked_add(Decimal::from(rhs))
81 .ok_or_else(|| {
82 ValueError::BinaryOperationOverflow {
83 lhs: Decimal(lhs),
84 rhs: I32(rhs),
85 operator: NumericBinaryOperator::Add,
86 }
87 .into()
88 })
89 .map(Decimal),
90 I64(rhs) => lhs
91 .checked_add(Decimal::from(rhs))
92 .ok_or_else(|| {
93 ValueError::BinaryOperationOverflow {
94 lhs: Decimal(lhs),
95 rhs: I64(rhs),
96 operator: NumericBinaryOperator::Add,
97 }
98 .into()
99 })
100 .map(Decimal),
101 I128(rhs) => lhs
102 .checked_add(Decimal::from(rhs))
103 .ok_or_else(|| {
104 ValueError::BinaryOperationOverflow {
105 lhs: Decimal(lhs),
106 rhs: I128(rhs),
107 operator: NumericBinaryOperator::Add,
108 }
109 .into()
110 })
111 .map(Decimal),
112 U8(rhs) => lhs
113 .checked_add(Decimal::from(rhs))
114 .ok_or_else(|| {
115 ValueError::BinaryOperationOverflow {
116 lhs: Decimal(lhs),
117 rhs: U8(rhs),
118 operator: NumericBinaryOperator::Add,
119 }
120 .into()
121 })
122 .map(Decimal),
123 U16(rhs) => lhs
124 .checked_add(Decimal::from(rhs))
125 .ok_or_else(|| {
126 ValueError::BinaryOperationOverflow {
127 lhs: Decimal(lhs),
128 rhs: U16(rhs),
129 operator: NumericBinaryOperator::Add,
130 }
131 .into()
132 })
133 .map(Decimal),
134 U32(rhs) => lhs
135 .checked_add(Decimal::from(rhs))
136 .ok_or_else(|| {
137 ValueError::BinaryOperationOverflow {
138 lhs: Decimal(lhs),
139 rhs: U32(rhs),
140 operator: NumericBinaryOperator::Add,
141 }
142 .into()
143 })
144 .map(Decimal),
145 U64(rhs) => lhs
146 .checked_add(Decimal::from(rhs))
147 .ok_or_else(|| {
148 ValueError::BinaryOperationOverflow {
149 lhs: Decimal(lhs),
150 rhs: U64(rhs),
151 operator: NumericBinaryOperator::Add,
152 }
153 .into()
154 })
155 .map(Decimal),
156 U128(rhs) => lhs
157 .checked_add(Decimal::from(rhs))
158 .ok_or_else(|| {
159 ValueError::BinaryOperationOverflow {
160 lhs: Decimal(lhs),
161 rhs: U128(rhs),
162 operator: NumericBinaryOperator::Add,
163 }
164 .into()
165 })
166 .map(Decimal),
167
168 F32(rhs) => Decimal::from_f32_retain(rhs)
169 .map(|x| {
170 lhs.checked_add(x)
171 .ok_or_else(|| {
172 ValueError::BinaryOperationOverflow {
173 lhs: Decimal(lhs),
174 rhs: F32(rhs),
175 operator: NumericBinaryOperator::Add,
176 }
177 .into()
178 })
179 .map(Decimal)
180 })
181 .unwrap_or_else(|| {
182 Err(ValueError::FloatToDecimalConversionFailure(rhs.into()).into())
183 }),
184 F64(rhs) => Decimal::from_f64_retain(rhs)
185 .map(|x| {
186 lhs.checked_add(x)
187 .ok_or_else(|| {
188 ValueError::BinaryOperationOverflow {
189 lhs: Decimal(lhs),
190 rhs: F64(rhs),
191 operator: NumericBinaryOperator::Add,
192 }
193 .into()
194 })
195 .map(Decimal)
196 })
197 .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())),
198 Decimal(rhs) => lhs
199 .checked_add(rhs)
200 .ok_or_else(|| {
201 ValueError::BinaryOperationOverflow {
202 lhs: Decimal(lhs),
203 rhs: Decimal(rhs),
204 operator: NumericBinaryOperator::Add,
205 }
206 .into()
207 })
208 .map(Decimal),
209 Null => Ok(Null),
210 _ => Err(ValueError::NonNumericMathOperation {
211 lhs: Decimal(lhs),
212 operator: NumericBinaryOperator::Add,
213 rhs: rhs.clone(),
214 }
215 .into()),
216 }
217 }
218
219 fn try_subtract(&self, rhs: &Self::Rhs) -> Result<Value> {
220 let lhs = *self;
221
222 match *rhs {
223 I8(rhs) => lhs
224 .checked_sub(Decimal::from(rhs))
225 .ok_or_else(|| {
226 ValueError::BinaryOperationOverflow {
227 lhs: Decimal(lhs),
228 rhs: I8(rhs),
229 operator: NumericBinaryOperator::Subtract,
230 }
231 .into()
232 })
233 .map(Decimal),
234 I32(rhs) => lhs
235 .checked_sub(Decimal::from(rhs))
236 .ok_or_else(|| {
237 ValueError::BinaryOperationOverflow {
238 lhs: Decimal(lhs),
239 rhs: I32(rhs),
240 operator: NumericBinaryOperator::Subtract,
241 }
242 .into()
243 })
244 .map(Decimal),
245 I64(rhs) => lhs
246 .checked_sub(Decimal::from(rhs))
247 .ok_or_else(|| {
248 ValueError::BinaryOperationOverflow {
249 lhs: Decimal(lhs),
250 rhs: I64(rhs),
251 operator: NumericBinaryOperator::Subtract,
252 }
253 .into()
254 })
255 .map(Decimal),
256 I128(rhs) => lhs
257 .checked_sub(Decimal::from(rhs))
258 .ok_or_else(|| {
259 ValueError::BinaryOperationOverflow {
260 lhs: Decimal(lhs),
261 rhs: I128(rhs),
262 operator: NumericBinaryOperator::Subtract,
263 }
264 .into()
265 })
266 .map(Decimal),
267 U8(rhs) => lhs
268 .checked_sub(Decimal::from(rhs))
269 .ok_or_else(|| {
270 ValueError::BinaryOperationOverflow {
271 lhs: Decimal(lhs),
272 rhs: U8(rhs),
273 operator: NumericBinaryOperator::Subtract,
274 }
275 .into()
276 })
277 .map(Decimal),
278 U16(rhs) => lhs
279 .checked_sub(Decimal::from(rhs))
280 .ok_or_else(|| {
281 ValueError::BinaryOperationOverflow {
282 lhs: Decimal(lhs),
283 rhs: U16(rhs),
284 operator: NumericBinaryOperator::Subtract,
285 }
286 .into()
287 })
288 .map(Decimal),
289 U32(rhs) => lhs
290 .checked_sub(Decimal::from(rhs))
291 .ok_or_else(|| {
292 ValueError::BinaryOperationOverflow {
293 lhs: Decimal(lhs),
294 rhs: U32(rhs),
295 operator: NumericBinaryOperator::Subtract,
296 }
297 .into()
298 })
299 .map(Decimal),
300 U64(rhs) => lhs
301 .checked_sub(Decimal::from(rhs))
302 .ok_or_else(|| {
303 ValueError::BinaryOperationOverflow {
304 lhs: Decimal(lhs),
305 rhs: U64(rhs),
306 operator: NumericBinaryOperator::Subtract,
307 }
308 .into()
309 })
310 .map(Decimal),
311 U128(rhs) => lhs
312 .checked_sub(Decimal::from(rhs))
313 .ok_or_else(|| {
314 ValueError::BinaryOperationOverflow {
315 lhs: Decimal(lhs),
316 rhs: U128(rhs),
317 operator: NumericBinaryOperator::Subtract,
318 }
319 .into()
320 })
321 .map(Decimal),
322
323 F32(rhs) => Decimal::from_f32_retain(rhs)
324 .map(|x| {
325 lhs.checked_sub(x)
326 .ok_or_else(|| {
327 ValueError::BinaryOperationOverflow {
328 lhs: Decimal(lhs),
329 rhs: F32(rhs),
330 operator: NumericBinaryOperator::Subtract,
331 }
332 .into()
333 })
334 .map(Decimal)
335 })
336 .unwrap_or_else(|| {
337 Err(ValueError::FloatToDecimalConversionFailure(rhs.into()).into())
338 }),
339 F64(rhs) => Decimal::from_f64_retain(rhs)
340 .map(|x| {
341 lhs.checked_sub(x)
342 .ok_or_else(|| {
343 ValueError::BinaryOperationOverflow {
344 lhs: Decimal(lhs),
345 rhs: F64(rhs),
346 operator: NumericBinaryOperator::Subtract,
347 }
348 .into()
349 })
350 .map(Decimal)
351 })
352 .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())),
353 Decimal(rhs) => lhs
354 .checked_sub(rhs)
355 .ok_or_else(|| {
356 ValueError::BinaryOperationOverflow {
357 lhs: Decimal(lhs),
358 operator: NumericBinaryOperator::Subtract,
359 rhs: Decimal(rhs),
360 }
361 .into()
362 })
363 .map(Decimal),
364 Null => Ok(Null),
365 _ => Err(ValueError::NonNumericMathOperation {
366 lhs: Decimal(lhs),
367 operator: NumericBinaryOperator::Subtract,
368 rhs: rhs.clone(),
369 }
370 .into()),
371 }
372 }
373
374 fn try_multiply(&self, rhs: &Self::Rhs) -> Result<Value> {
375 let lhs = *self;
376
377 match *rhs {
378 I8(rhs) => lhs
379 .checked_mul(Decimal::from(rhs))
380 .ok_or_else(|| {
381 ValueError::BinaryOperationOverflow {
382 lhs: Decimal(lhs),
383 rhs: I8(rhs),
384 operator: NumericBinaryOperator::Multiply,
385 }
386 .into()
387 })
388 .map(Decimal),
389 I32(rhs) => lhs
390 .checked_mul(Decimal::from(rhs))
391 .ok_or_else(|| {
392 ValueError::BinaryOperationOverflow {
393 lhs: Decimal(lhs),
394 rhs: I32(rhs),
395 operator: NumericBinaryOperator::Multiply,
396 }
397 .into()
398 })
399 .map(Decimal),
400 I64(rhs) => lhs
401 .checked_mul(Decimal::from(rhs))
402 .ok_or_else(|| {
403 ValueError::BinaryOperationOverflow {
404 lhs: Decimal(lhs),
405 rhs: I64(rhs),
406 operator: NumericBinaryOperator::Multiply,
407 }
408 .into()
409 })
410 .map(Decimal),
411 I128(rhs) => lhs
412 .checked_mul(Decimal::from(rhs))
413 .ok_or_else(|| {
414 ValueError::BinaryOperationOverflow {
415 lhs: Decimal(lhs),
416 rhs: I128(rhs),
417 operator: NumericBinaryOperator::Multiply,
418 }
419 .into()
420 })
421 .map(Decimal),
422 U8(rhs) => lhs
423 .checked_mul(Decimal::from(rhs))
424 .ok_or_else(|| {
425 ValueError::BinaryOperationOverflow {
426 lhs: Decimal(lhs),
427 rhs: U8(rhs),
428 operator: NumericBinaryOperator::Multiply,
429 }
430 .into()
431 })
432 .map(Decimal),
433 U16(rhs) => lhs
434 .checked_mul(Decimal::from(rhs))
435 .ok_or_else(|| {
436 ValueError::BinaryOperationOverflow {
437 lhs: Decimal(lhs),
438 rhs: U16(rhs),
439 operator: NumericBinaryOperator::Multiply,
440 }
441 .into()
442 })
443 .map(Decimal),
444 U32(rhs) => lhs
445 .checked_mul(Decimal::from(rhs))
446 .ok_or_else(|| {
447 ValueError::BinaryOperationOverflow {
448 lhs: Decimal(lhs),
449 rhs: U32(rhs),
450 operator: NumericBinaryOperator::Multiply,
451 }
452 .into()
453 })
454 .map(Decimal),
455 U64(rhs) => lhs
456 .checked_mul(Decimal::from(rhs))
457 .ok_or_else(|| {
458 ValueError::BinaryOperationOverflow {
459 lhs: Decimal(lhs),
460 rhs: U64(rhs),
461 operator: NumericBinaryOperator::Multiply,
462 }
463 .into()
464 })
465 .map(Decimal),
466 U128(rhs) => lhs
467 .checked_mul(Decimal::from(rhs))
468 .ok_or_else(|| {
469 ValueError::BinaryOperationOverflow {
470 lhs: Decimal(lhs),
471 rhs: U128(rhs),
472 operator: NumericBinaryOperator::Multiply,
473 }
474 .into()
475 })
476 .map(Decimal),
477
478 F32(rhs) => Decimal::from_f32_retain(rhs)
479 .map(|x| {
480 lhs.checked_mul(x)
481 .ok_or_else(|| {
482 ValueError::BinaryOperationOverflow {
483 lhs: Decimal(lhs),
484 rhs: F32(rhs),
485 operator: NumericBinaryOperator::Multiply,
486 }
487 .into()
488 })
489 .map(Decimal)
490 })
491 .unwrap_or_else(|| {
492 Err(ValueError::FloatToDecimalConversionFailure(rhs.into()).into())
493 }),
494 F64(rhs) => Decimal::from_f64_retain(rhs)
495 .map(|x| {
496 lhs.checked_mul(x)
497 .ok_or_else(|| {
498 ValueError::BinaryOperationOverflow {
499 lhs: Decimal(lhs),
500 rhs: F64(rhs),
501 operator: NumericBinaryOperator::Multiply,
502 }
503 .into()
504 })
505 .map(Decimal)
506 })
507 .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())),
508 Decimal(rhs) => lhs
509 .checked_mul(rhs)
510 .ok_or_else(|| {
511 ValueError::BinaryOperationOverflow {
512 lhs: Decimal(lhs),
513 operator: NumericBinaryOperator::Multiply,
514 rhs: Decimal(rhs),
515 }
516 .into()
517 })
518 .map(Decimal),
519 Null => Ok(Null),
520 _ => Err(ValueError::NonNumericMathOperation {
521 lhs: Decimal(lhs),
522 operator: NumericBinaryOperator::Multiply,
523 rhs: rhs.clone(),
524 }
525 .into()),
526 }
527 }
528
529 fn try_divide(&self, rhs: &Self::Rhs) -> Result<Value> {
530 let lhs = *self;
531
532 match *rhs {
533 I8(rhs) => lhs
534 .checked_div(Decimal::from(rhs))
535 .ok_or_else(|| {
536 ValueError::BinaryOperationOverflow {
537 lhs: Decimal(lhs),
538 rhs: I8(rhs),
539 operator: NumericBinaryOperator::Divide,
540 }
541 .into()
542 })
543 .map(Decimal),
544 I32(rhs) => lhs
545 .checked_div(Decimal::from(rhs))
546 .ok_or_else(|| {
547 ValueError::BinaryOperationOverflow {
548 lhs: Decimal(lhs),
549 rhs: I32(rhs),
550 operator: NumericBinaryOperator::Divide,
551 }
552 .into()
553 })
554 .map(Decimal),
555 I64(rhs) => lhs
556 .checked_div(Decimal::from(rhs))
557 .ok_or_else(|| {
558 ValueError::BinaryOperationOverflow {
559 lhs: Decimal(lhs),
560 rhs: I64(rhs),
561 operator: NumericBinaryOperator::Divide,
562 }
563 .into()
564 })
565 .map(Decimal),
566 I128(rhs) => lhs
567 .checked_div(Decimal::from(rhs))
568 .ok_or_else(|| {
569 ValueError::BinaryOperationOverflow {
570 lhs: Decimal(lhs),
571 rhs: I128(rhs),
572 operator: NumericBinaryOperator::Divide,
573 }
574 .into()
575 })
576 .map(Decimal),
577 U8(rhs) => lhs
578 .checked_div(Decimal::from(rhs))
579 .ok_or_else(|| {
580 ValueError::BinaryOperationOverflow {
581 lhs: Decimal(lhs),
582 rhs: U8(rhs),
583 operator: NumericBinaryOperator::Divide,
584 }
585 .into()
586 })
587 .map(Decimal),
588 U16(rhs) => lhs
589 .checked_div(Decimal::from(rhs))
590 .ok_or_else(|| {
591 ValueError::BinaryOperationOverflow {
592 lhs: Decimal(lhs),
593 rhs: U16(rhs),
594 operator: NumericBinaryOperator::Divide,
595 }
596 .into()
597 })
598 .map(Decimal),
599 U32(rhs) => lhs
600 .checked_div(Decimal::from(rhs))
601 .ok_or_else(|| {
602 ValueError::BinaryOperationOverflow {
603 lhs: Decimal(lhs),
604 rhs: U32(rhs),
605 operator: NumericBinaryOperator::Divide,
606 }
607 .into()
608 })
609 .map(Decimal),
610 U64(rhs) => lhs
611 .checked_div(Decimal::from(rhs))
612 .ok_or_else(|| {
613 ValueError::BinaryOperationOverflow {
614 lhs: Decimal(lhs),
615 rhs: U64(rhs),
616 operator: NumericBinaryOperator::Divide,
617 }
618 .into()
619 })
620 .map(Decimal),
621 U128(rhs) => lhs
622 .checked_div(Decimal::from(rhs))
623 .ok_or_else(|| {
624 ValueError::BinaryOperationOverflow {
625 lhs: Decimal(lhs),
626 rhs: U128(rhs),
627 operator: NumericBinaryOperator::Divide,
628 }
629 .into()
630 })
631 .map(Decimal),
632
633 F32(rhs) => Decimal::from_f32_retain(rhs)
634 .map(|x| {
635 lhs.checked_div(x)
636 .ok_or_else(|| {
637 ValueError::BinaryOperationOverflow {
638 lhs: Decimal(lhs),
639 rhs: F32(rhs),
640 operator: NumericBinaryOperator::Divide,
641 }
642 .into()
643 })
644 .map(Decimal)
645 })
646 .unwrap_or_else(|| {
647 Err(ValueError::FloatToDecimalConversionFailure(rhs.into()).into())
648 }),
649 F64(rhs) => Decimal::from_f64_retain(rhs)
650 .map(|x| {
651 lhs.checked_div(x)
652 .ok_or_else(|| {
653 ValueError::BinaryOperationOverflow {
654 lhs: Decimal(lhs),
655 rhs: F64(rhs),
656 operator: NumericBinaryOperator::Divide,
657 }
658 .into()
659 })
660 .map(Decimal)
661 })
662 .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())),
663 Decimal(rhs) => lhs
664 .checked_div(rhs)
665 .ok_or_else(|| {
666 ValueError::BinaryOperationOverflow {
667 lhs: Decimal(lhs),
668 operator: NumericBinaryOperator::Divide,
669 rhs: Decimal(rhs),
670 }
671 .into()
672 })
673 .map(Decimal),
674 Null => Ok(Null),
675 _ => Err(ValueError::NonNumericMathOperation {
676 lhs: Decimal(lhs),
677 operator: NumericBinaryOperator::Divide,
678 rhs: rhs.clone(),
679 }
680 .into()),
681 }
682 }
683
684 fn try_modulo(&self, rhs: &Self::Rhs) -> Result<Value> {
685 let lhs = *self;
686
687 match *rhs {
688 I8(rhs) => lhs
689 .checked_rem(Decimal::from(rhs))
690 .map(|x| Ok(Decimal(x)))
691 .unwrap_or_else(|| {
692 Err(ValueError::BinaryOperationOverflow {
693 lhs: Decimal(lhs),
694 operator: NumericBinaryOperator::Modulo,
695 rhs: I8(rhs),
696 }
697 .into())
698 }),
699 I32(rhs) => lhs
700 .checked_rem(Decimal::from(rhs))
701 .map(|x| Ok(Decimal(x)))
702 .unwrap_or_else(|| {
703 Err(ValueError::BinaryOperationOverflow {
704 lhs: Decimal(lhs),
705 operator: NumericBinaryOperator::Modulo,
706 rhs: I32(rhs),
707 }
708 .into())
709 }),
710 I64(rhs) => lhs
711 .checked_rem(Decimal::from(rhs))
712 .map(|x| Ok(Decimal(x)))
713 .unwrap_or_else(|| {
714 Err(ValueError::BinaryOperationOverflow {
715 lhs: Decimal(lhs),
716 operator: NumericBinaryOperator::Modulo,
717 rhs: I64(rhs),
718 }
719 .into())
720 }),
721 I128(rhs) => lhs
722 .checked_rem(Decimal::from(rhs))
723 .map(|x| Ok(Decimal(x)))
724 .unwrap_or_else(|| {
725 Err(ValueError::BinaryOperationOverflow {
726 lhs: Decimal(lhs),
727 operator: NumericBinaryOperator::Modulo,
728 rhs: I128(rhs),
729 }
730 .into())
731 }),
732 U8(rhs) => lhs
733 .checked_rem(Decimal::from(rhs))
734 .ok_or_else(|| {
735 ValueError::BinaryOperationOverflow {
736 lhs: Decimal(lhs),
737 rhs: U8(rhs),
738 operator: NumericBinaryOperator::Modulo,
739 }
740 .into()
741 })
742 .map(Decimal),
743 U16(rhs) => lhs
744 .checked_rem(Decimal::from(rhs))
745 .ok_or_else(|| {
746 ValueError::BinaryOperationOverflow {
747 lhs: Decimal(lhs),
748 rhs: U16(rhs),
749 operator: NumericBinaryOperator::Modulo,
750 }
751 .into()
752 })
753 .map(Decimal),
754 U32(rhs) => lhs
755 .checked_rem(Decimal::from(rhs))
756 .ok_or_else(|| {
757 ValueError::BinaryOperationOverflow {
758 lhs: Decimal(lhs),
759 rhs: U32(rhs),
760 operator: NumericBinaryOperator::Modulo,
761 }
762 .into()
763 })
764 .map(Decimal),
765 U64(rhs) => lhs
766 .checked_rem(Decimal::from(rhs))
767 .ok_or_else(|| {
768 ValueError::BinaryOperationOverflow {
769 lhs: Decimal(lhs),
770 rhs: U64(rhs),
771 operator: NumericBinaryOperator::Modulo,
772 }
773 .into()
774 })
775 .map(Decimal),
776 U128(rhs) => lhs
777 .checked_rem(Decimal::from(rhs))
778 .ok_or_else(|| {
779 ValueError::BinaryOperationOverflow {
780 lhs: Decimal(lhs),
781 rhs: U128(rhs),
782 operator: NumericBinaryOperator::Modulo,
783 }
784 .into()
785 })
786 .map(Decimal),
787
788 F32(rhs) => match Decimal::from_f32_retain(rhs) {
789 Some(x) => lhs
790 .checked_rem(x)
791 .map(|y| Ok(Decimal(y)))
792 .unwrap_or_else(|| {
793 Err(ValueError::BinaryOperationOverflow {
794 lhs: Decimal(lhs),
795 operator: NumericBinaryOperator::Modulo,
796 rhs: F32(rhs),
797 }
798 .into())
799 }),
800 _ => Err(ValueError::FloatToDecimalConversionFailure(rhs.into()).into()),
801 },
802 F64(rhs) => match Decimal::from_f64_retain(rhs) {
803 Some(x) => lhs
804 .checked_rem(x)
805 .map(|y| Ok(Decimal(y)))
806 .unwrap_or_else(|| {
807 Err(ValueError::BinaryOperationOverflow {
808 lhs: Decimal(lhs),
809 operator: NumericBinaryOperator::Modulo,
810 rhs: F64(rhs),
811 }
812 .into())
813 }),
814 _ => Err(ValueError::FloatToDecimalConversionFailure(rhs).into()),
815 },
816 Decimal(rhs) => lhs
817 .checked_rem(rhs)
818 .ok_or_else(|| {
819 ValueError::BinaryOperationOverflow {
820 lhs: Decimal(lhs),
821 operator: NumericBinaryOperator::Modulo,
822 rhs: Decimal(rhs),
823 }
824 .into()
825 })
826 .map(Decimal),
827 Null => Ok(Null),
828 _ => Err(ValueError::NonNumericMathOperation {
829 lhs: Decimal(lhs),
830 operator: NumericBinaryOperator::Modulo,
831 rhs: rhs.clone(),
832 }
833 .into()),
834 }
835 }
836}
837
838#[cfg(test)]
839mod tests {
840 use {
841 super::{TryBinaryOperator, Value::*},
842 crate::data::{NumericBinaryOperator, ValueError},
843 rust_decimal::prelude::Decimal,
844 std::cmp::Ordering,
845 };
846
847 #[test]
848 fn test_extremes() {
849 let base = Decimal::ONE;
850
851 assert_eq!(
852 Decimal::MAX.try_add(&Decimal(Decimal::ONE)),
853 Err(ValueError::BinaryOperationOverflow {
854 lhs: Decimal(Decimal::MAX),
855 rhs: Decimal(Decimal::ONE),
856 operator: NumericBinaryOperator::Add,
857 }
858 .into())
859 );
860
861 assert_eq!(
862 Decimal::MAX.try_add(&I8(1)),
863 Err(ValueError::BinaryOperationOverflow {
864 lhs: Decimal(Decimal::MAX),
865 rhs: I8(1),
866 operator: NumericBinaryOperator::Add,
867 }
868 .into())
869 );
870 assert_eq!(
871 Decimal::MAX.try_add(&I32(1)),
872 Err(ValueError::BinaryOperationOverflow {
873 lhs: Decimal(Decimal::MAX),
874 rhs: I32(1),
875 operator: NumericBinaryOperator::Add,
876 }
877 .into())
878 );
879 assert_eq!(
880 Decimal::MAX.try_add(&I64(1)),
881 Err(ValueError::BinaryOperationOverflow {
882 lhs: Decimal(Decimal::MAX),
883 rhs: I64(1),
884 operator: NumericBinaryOperator::Add,
885 }
886 .into())
887 );
888 assert_eq!(
889 Decimal::MAX.try_add(&I128(1)),
890 Err(ValueError::BinaryOperationOverflow {
891 lhs: Decimal(Decimal::MAX),
892 rhs: I128(1),
893 operator: NumericBinaryOperator::Add,
894 }
895 .into())
896 );
897 assert_eq!(
898 Decimal::MAX.try_add(&U8(1)),
899 Err(ValueError::BinaryOperationOverflow {
900 lhs: Decimal(Decimal::MAX),
901 rhs: U8(1),
902 operator: NumericBinaryOperator::Add,
903 }
904 .into())
905 );
906
907 assert_eq!(
908 Decimal::MAX.try_add(&U16(1)),
909 Err(ValueError::BinaryOperationOverflow {
910 lhs: Decimal(Decimal::MAX),
911 rhs: U16(1),
912 operator: NumericBinaryOperator::Add,
913 }
914 .into())
915 );
916 assert_eq!(
917 Decimal::MAX.try_add(&U32(1)),
918 Err(ValueError::BinaryOperationOverflow {
919 lhs: Decimal(Decimal::MAX),
920 rhs: U32(1),
921 operator: NumericBinaryOperator::Add,
922 }
923 .into())
924 );
925 assert_eq!(
926 Decimal::MAX.try_add(&U64(1)),
927 Err(ValueError::BinaryOperationOverflow {
928 lhs: Decimal(Decimal::MAX),
929 rhs: U64(1),
930 operator: NumericBinaryOperator::Add,
931 }
932 .into())
933 );
934 assert_eq!(
935 Decimal::MAX.try_add(&U128(1)),
936 Err(ValueError::BinaryOperationOverflow {
937 lhs: Decimal(Decimal::MAX),
938 rhs: U128(1),
939 operator: NumericBinaryOperator::Add,
940 }
941 .into())
942 );
943 assert_eq!(
944 Decimal::MAX.try_add(&F32(1.0_f32)),
945 Err(ValueError::BinaryOperationOverflow {
946 lhs: Decimal(Decimal::MAX),
947 rhs: F32(1.0_f32),
948 operator: NumericBinaryOperator::Add,
949 }
950 .into())
951 );
952 assert_eq!(
953 Decimal::MAX.try_add(&F64(1.0)),
954 Err(ValueError::BinaryOperationOverflow {
955 lhs: Decimal(Decimal::MAX),
956 rhs: F64(1.0),
957 operator: NumericBinaryOperator::Add,
958 }
959 .into())
960 );
961
962 assert_eq!(
963 Decimal::MIN.try_subtract(&I8(1)),
964 Err(ValueError::BinaryOperationOverflow {
965 lhs: Decimal(Decimal::MIN),
966 rhs: I8(1),
967 operator: NumericBinaryOperator::Subtract,
968 }
969 .into())
970 );
971 assert_eq!(
972 Decimal::MIN.try_subtract(&I32(1)),
973 Err(ValueError::BinaryOperationOverflow {
974 lhs: Decimal(Decimal::MIN),
975 rhs: I32(1),
976 operator: NumericBinaryOperator::Subtract,
977 }
978 .into())
979 );
980 assert_eq!(
981 Decimal::MIN.try_subtract(&I64(1)),
982 Err(ValueError::BinaryOperationOverflow {
983 lhs: Decimal(Decimal::MIN),
984 rhs: I64(1),
985 operator: NumericBinaryOperator::Subtract,
986 }
987 .into())
988 );
989 assert_eq!(
990 Decimal::MIN.try_subtract(&I128(1)),
991 Err(ValueError::BinaryOperationOverflow {
992 lhs: Decimal(Decimal::MIN),
993 rhs: I128(1),
994 operator: NumericBinaryOperator::Subtract,
995 }
996 .into())
997 );
998 assert_eq!(
999 Decimal::MIN.try_subtract(&U8(1)),
1000 Err(ValueError::BinaryOperationOverflow {
1001 lhs: Decimal(Decimal::MIN),
1002 rhs: U8(1),
1003 operator: NumericBinaryOperator::Subtract,
1004 }
1005 .into())
1006 );
1007 assert_eq!(
1008 Decimal::MIN.try_subtract(&U16(1)),
1009 Err(ValueError::BinaryOperationOverflow {
1010 lhs: Decimal(Decimal::MIN),
1011 rhs: U16(1),
1012 operator: NumericBinaryOperator::Subtract,
1013 }
1014 .into())
1015 );
1016 assert_eq!(
1017 Decimal::MIN.try_subtract(&U32(1)),
1018 Err(ValueError::BinaryOperationOverflow {
1019 lhs: Decimal(Decimal::MIN),
1020 rhs: U32(1),
1021 operator: NumericBinaryOperator::Subtract,
1022 }
1023 .into())
1024 );
1025 assert_eq!(
1026 Decimal::MIN.try_subtract(&U64(1)),
1027 Err(ValueError::BinaryOperationOverflow {
1028 lhs: Decimal(Decimal::MIN),
1029 rhs: U64(1),
1030 operator: NumericBinaryOperator::Subtract,
1031 }
1032 .into())
1033 );
1034 assert_eq!(
1035 Decimal::MIN.try_subtract(&U128(1)),
1036 Err(ValueError::BinaryOperationOverflow {
1037 lhs: Decimal(Decimal::MIN),
1038 rhs: U128(1),
1039 operator: NumericBinaryOperator::Subtract,
1040 }
1041 .into())
1042 );
1043 assert_eq!(
1044 Decimal::MIN.try_subtract(&F32(1.0_f32)),
1045 Err(ValueError::BinaryOperationOverflow {
1046 lhs: Decimal(Decimal::MIN),
1047 rhs: F32(1.0_f32),
1048 operator: NumericBinaryOperator::Subtract,
1049 }
1050 .into())
1051 );
1052 assert_eq!(
1053 Decimal::MIN.try_subtract(&F64(1.0)),
1054 Err(ValueError::BinaryOperationOverflow {
1055 lhs: Decimal(Decimal::MIN),
1056 rhs: F64(1.0),
1057 operator: NumericBinaryOperator::Subtract,
1058 }
1059 .into())
1060 );
1061
1062 assert_eq!(
1063 Decimal::MIN.try_subtract(&Decimal(Decimal::ONE)),
1064 Err(ValueError::BinaryOperationOverflow {
1065 lhs: Decimal(Decimal::MIN),
1066 rhs: Decimal(Decimal::ONE),
1067 operator: NumericBinaryOperator::Subtract,
1068 }
1069 .into())
1070 );
1071
1072 assert_eq!(
1073 Decimal::MAX.try_multiply(&I8(2)),
1074 Err(ValueError::BinaryOperationOverflow {
1075 lhs: Decimal(Decimal::MAX),
1076 rhs: I8(2),
1077 operator: NumericBinaryOperator::Multiply,
1078 }
1079 .into())
1080 );
1081 assert_eq!(
1082 Decimal::MAX.try_multiply(&I32(2)),
1083 Err(ValueError::BinaryOperationOverflow {
1084 lhs: Decimal(Decimal::MAX),
1085 rhs: I32(2),
1086 operator: NumericBinaryOperator::Multiply,
1087 }
1088 .into())
1089 );
1090 assert_eq!(
1091 Decimal::MAX.try_multiply(&I64(2)),
1092 Err(ValueError::BinaryOperationOverflow {
1093 lhs: Decimal(Decimal::MAX),
1094 rhs: I64(2),
1095 operator: NumericBinaryOperator::Multiply,
1096 }
1097 .into())
1098 );
1099 assert_eq!(
1100 Decimal::MAX.try_multiply(&I128(2)),
1101 Err(ValueError::BinaryOperationOverflow {
1102 lhs: Decimal(Decimal::MAX),
1103 rhs: I128(2),
1104 operator: NumericBinaryOperator::Multiply,
1105 }
1106 .into())
1107 );
1108 assert_eq!(
1109 Decimal::MAX.try_multiply(&U8(2)),
1110 Err(ValueError::BinaryOperationOverflow {
1111 lhs: Decimal(Decimal::MAX),
1112 rhs: U8(2),
1113 operator: NumericBinaryOperator::Multiply,
1114 }
1115 .into())
1116 );
1117 assert_eq!(
1118 Decimal::MAX.try_multiply(&U16(2)),
1119 Err(ValueError::BinaryOperationOverflow {
1120 lhs: Decimal(Decimal::MAX),
1121 rhs: U16(2),
1122 operator: NumericBinaryOperator::Multiply,
1123 }
1124 .into())
1125 );
1126
1127 assert_eq!(
1128 Decimal::MAX.try_multiply(&U32(2)),
1129 Err(ValueError::BinaryOperationOverflow {
1130 lhs: Decimal(Decimal::MAX),
1131 rhs: U32(2),
1132 operator: NumericBinaryOperator::Multiply,
1133 }
1134 .into())
1135 );
1136 assert_eq!(
1137 Decimal::MAX.try_multiply(&U64(2)),
1138 Err(ValueError::BinaryOperationOverflow {
1139 lhs: Decimal(Decimal::MAX),
1140 rhs: U64(2),
1141 operator: NumericBinaryOperator::Multiply,
1142 }
1143 .into())
1144 );
1145 assert_eq!(
1146 Decimal::MAX.try_multiply(&U128(2)),
1147 Err(ValueError::BinaryOperationOverflow {
1148 lhs: Decimal(Decimal::MAX),
1149 rhs: U128(2),
1150 operator: NumericBinaryOperator::Multiply,
1151 }
1152 .into())
1153 );
1154 assert_eq!(
1155 Decimal::MAX.try_multiply(&F32(2.0_f32)),
1156 Err(ValueError::BinaryOperationOverflow {
1157 lhs: Decimal(Decimal::MAX),
1158 rhs: F32(2.0_f32),
1159 operator: NumericBinaryOperator::Multiply,
1160 }
1161 .into())
1162 );
1163 assert_eq!(
1164 Decimal::MAX.try_multiply(&F64(2.0)),
1165 Err(ValueError::BinaryOperationOverflow {
1166 lhs: Decimal(Decimal::MAX),
1167 rhs: F64(2.0),
1168 operator: NumericBinaryOperator::Multiply,
1169 }
1170 .into())
1171 );
1172
1173 assert_eq!(
1174 Decimal::MAX.try_multiply(&Decimal(Decimal::TWO)),
1175 Err(ValueError::BinaryOperationOverflow {
1176 lhs: Decimal(Decimal::MAX),
1177 rhs: Decimal(Decimal::TWO),
1178 operator: NumericBinaryOperator::Multiply,
1179 }
1180 .into())
1181 );
1182
1183 assert_eq!(
1185 base.try_divide(&I8(0)),
1186 Err(ValueError::BinaryOperationOverflow {
1187 lhs: Decimal(base),
1188 rhs: I8(0),
1189 operator: NumericBinaryOperator::Divide,
1190 }
1191 .into())
1192 );
1193 assert_eq!(
1194 base.try_divide(&I32(0)),
1195 Err(ValueError::BinaryOperationOverflow {
1196 lhs: Decimal(base),
1197 rhs: I32(0),
1198 operator: NumericBinaryOperator::Divide,
1199 }
1200 .into())
1201 );
1202 assert_eq!(
1203 base.try_divide(&I64(0)),
1204 Err(ValueError::BinaryOperationOverflow {
1205 lhs: Decimal(base),
1206 rhs: I64(0),
1207 operator: NumericBinaryOperator::Divide,
1208 }
1209 .into())
1210 );
1211
1212 assert_eq!(
1213 base.try_divide(&I128(0)),
1214 Err(ValueError::BinaryOperationOverflow {
1215 lhs: Decimal(base),
1216 rhs: I128(0),
1217 operator: NumericBinaryOperator::Divide,
1218 }
1219 .into())
1220 );
1221 assert_eq!(
1222 base.try_divide(&U8(0)),
1223 Err(ValueError::BinaryOperationOverflow {
1224 lhs: Decimal(base),
1225 rhs: U8(0),
1226 operator: NumericBinaryOperator::Divide,
1227 }
1228 .into())
1229 );
1230
1231 assert_eq!(
1232 base.try_divide(&U16(0)),
1233 Err(ValueError::BinaryOperationOverflow {
1234 lhs: Decimal(base),
1235 rhs: U16(0),
1236 operator: NumericBinaryOperator::Divide,
1237 }
1238 .into())
1239 );
1240 assert_eq!(
1241 base.try_divide(&U32(0)),
1242 Err(ValueError::BinaryOperationOverflow {
1243 lhs: Decimal(base),
1244 rhs: U32(0),
1245 operator: NumericBinaryOperator::Divide,
1246 }
1247 .into())
1248 );
1249 assert_eq!(
1250 base.try_divide(&U64(0)),
1251 Err(ValueError::BinaryOperationOverflow {
1252 lhs: Decimal(base),
1253 rhs: U64(0),
1254 operator: NumericBinaryOperator::Divide,
1255 }
1256 .into())
1257 );
1258 assert_eq!(
1259 base.try_divide(&U128(0)),
1260 Err(ValueError::BinaryOperationOverflow {
1261 lhs: Decimal(base),
1262 rhs: U128(0),
1263 operator: NumericBinaryOperator::Divide,
1264 }
1265 .into())
1266 );
1267 assert_eq!(
1268 base.try_divide(&F32(0.0_f32)),
1269 Err(ValueError::BinaryOperationOverflow {
1270 lhs: Decimal(base),
1271 rhs: F32(0.0_f32),
1272 operator: NumericBinaryOperator::Divide,
1273 }
1274 .into())
1275 );
1276 assert_eq!(
1277 base.try_divide(&F64(0.0)),
1278 Err(ValueError::BinaryOperationOverflow {
1279 lhs: Decimal(base),
1280 rhs: F64(0.0),
1281 operator: NumericBinaryOperator::Divide,
1282 }
1283 .into())
1284 );
1285
1286 assert_eq!(
1287 base.try_divide(&Decimal(Decimal::ZERO)),
1288 Err(ValueError::BinaryOperationOverflow {
1289 lhs: Decimal(base),
1290 rhs: Decimal(Decimal::ZERO),
1291 operator: NumericBinaryOperator::Divide,
1292 }
1293 .into())
1294 );
1295
1296 assert_eq!(
1298 base.try_modulo(&I8(0)),
1299 Err(ValueError::BinaryOperationOverflow {
1300 lhs: Decimal(base),
1301 rhs: I8(0),
1302 operator: NumericBinaryOperator::Modulo,
1303 }
1304 .into())
1305 );
1306 assert_eq!(
1307 base.try_modulo(&I32(0)),
1308 Err(ValueError::BinaryOperationOverflow {
1309 lhs: Decimal(base),
1310 rhs: I32(0),
1311 operator: NumericBinaryOperator::Modulo,
1312 }
1313 .into())
1314 );
1315 assert_eq!(
1316 base.try_modulo(&I64(0)),
1317 Err(ValueError::BinaryOperationOverflow {
1318 lhs: Decimal(base),
1319 rhs: I64(0),
1320 operator: NumericBinaryOperator::Modulo,
1321 }
1322 .into())
1323 );
1324
1325 assert_eq!(
1326 base.try_modulo(&I128(0)),
1327 Err(ValueError::BinaryOperationOverflow {
1328 lhs: Decimal(base),
1329 rhs: I128(0),
1330 operator: NumericBinaryOperator::Modulo,
1331 }
1332 .into())
1333 );
1334 assert_eq!(
1335 base.try_modulo(&U8(0)),
1336 Err(ValueError::BinaryOperationOverflow {
1337 lhs: Decimal(base),
1338 rhs: U8(0),
1339 operator: NumericBinaryOperator::Modulo,
1340 }
1341 .into())
1342 );
1343
1344 assert_eq!(
1345 base.try_modulo(&U16(0)),
1346 Err(ValueError::BinaryOperationOverflow {
1347 lhs: Decimal(base),
1348 rhs: U16(0),
1349 operator: NumericBinaryOperator::Modulo,
1350 }
1351 .into())
1352 );
1353 assert_eq!(
1354 base.try_modulo(&U32(0)),
1355 Err(ValueError::BinaryOperationOverflow {
1356 lhs: Decimal(base),
1357 rhs: U32(0),
1358 operator: NumericBinaryOperator::Modulo,
1359 }
1360 .into())
1361 );
1362 assert_eq!(
1363 base.try_modulo(&U64(0)),
1364 Err(ValueError::BinaryOperationOverflow {
1365 lhs: Decimal(base),
1366 rhs: U64(0),
1367 operator: NumericBinaryOperator::Modulo,
1368 }
1369 .into())
1370 );
1371 assert_eq!(
1372 base.try_modulo(&U128(0)),
1373 Err(ValueError::BinaryOperationOverflow {
1374 lhs: Decimal(base),
1375 rhs: U128(0),
1376 operator: NumericBinaryOperator::Modulo,
1377 }
1378 .into())
1379 );
1380 assert_eq!(
1381 base.try_modulo(&F32(0.0_f32)),
1382 Err(ValueError::BinaryOperationOverflow {
1383 lhs: Decimal(base),
1384 rhs: F32(0.0_f32),
1385 operator: NumericBinaryOperator::Modulo,
1386 }
1387 .into())
1388 );
1389 assert_eq!(
1390 base.try_modulo(&F64(0.0)),
1391 Err(ValueError::BinaryOperationOverflow {
1392 lhs: Decimal(base),
1393 rhs: F64(0.0),
1394 operator: NumericBinaryOperator::Modulo,
1395 }
1396 .into())
1397 );
1398
1399 assert_eq!(
1400 base.try_modulo(&Decimal(Decimal::ZERO)),
1401 Err(ValueError::BinaryOperationOverflow {
1402 lhs: Decimal(base),
1403 rhs: Decimal(Decimal::ZERO),
1404 operator: NumericBinaryOperator::Modulo,
1405 }
1406 .into())
1407 );
1408 }
1409
1410 #[test]
1411 fn eq() {
1412 let base = Decimal::ONE;
1413
1414 assert_eq!(base, I8(1));
1415 assert_eq!(base, I32(1));
1416 assert_eq!(base, I64(1));
1417 assert_eq!(base, I128(1));
1418 assert_eq!(base, U8(1));
1419 assert_eq!(base, U16(1));
1420 assert_eq!(base, U32(1));
1421 assert_eq!(base, U64(1));
1422 assert_eq!(base, U128(1));
1423 assert_eq!(base, F32(1.0_f32));
1424 assert_eq!(base, F64(1.0));
1425 assert_eq!(base, Decimal(Decimal::ONE));
1426
1427 assert_ne!(base, Bool(true));
1428 }
1429
1430 #[test]
1431 fn partial_cmp() {
1432 let base = Decimal::ONE;
1433
1434 assert_eq!(base.partial_cmp(&I8(1)), Some(Ordering::Equal));
1435 assert_eq!(base.partial_cmp(&I32(1)), Some(Ordering::Equal));
1436 assert_eq!(base.partial_cmp(&I64(1)), Some(Ordering::Equal));
1437 assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal));
1438 assert_eq!(base.partial_cmp(&U8(1)), Some(Ordering::Equal));
1439 assert_eq!(base.partial_cmp(&U16(1)), Some(Ordering::Equal));
1440 assert_eq!(base.partial_cmp(&U32(1)), Some(Ordering::Equal));
1441 assert_eq!(base.partial_cmp(&U64(1)), Some(Ordering::Equal));
1442 assert_eq!(base.partial_cmp(&U128(1)), Some(Ordering::Equal));
1443 assert_eq!(base.partial_cmp(&F32(1.0_f32)), Some(Ordering::Equal));
1444 assert_eq!(base.partial_cmp(&F64(1.0)), Some(Ordering::Equal));
1445 assert_eq!(
1446 base.partial_cmp(&Decimal(Decimal::ONE)),
1447 Some(Ordering::Equal)
1448 );
1449
1450 assert_eq!(base.partial_cmp(&Bool(true)), None);
1451 }
1452
1453 #[test]
1454 fn try_add() {
1455 let base = Decimal::ONE;
1456
1457 assert_eq!(base.try_add(&I8(1)), Ok(Decimal(Decimal::TWO)));
1458 assert_eq!(base.try_add(&I32(1)), Ok(Decimal(Decimal::TWO)));
1459 assert_eq!(base.try_add(&I64(1)), Ok(Decimal(Decimal::TWO)));
1460 assert_eq!(base.try_add(&I128(1)), Ok(Decimal(Decimal::TWO)));
1461 assert_eq!(base.try_add(&U8(1)), Ok(Decimal(Decimal::TWO)));
1462 assert_eq!(base.try_add(&U16(1)), Ok(Decimal(Decimal::TWO)));
1463 assert_eq!(base.try_add(&U32(1)), Ok(Decimal(Decimal::TWO)));
1464 assert_eq!(base.try_add(&U64(1)), Ok(Decimal(Decimal::TWO)));
1465 assert_eq!(base.try_add(&U128(1)), Ok(Decimal(Decimal::TWO)));
1466 assert_eq!(base.try_add(&F32(1.0_f32)), Ok(Decimal(Decimal::TWO)));
1467 assert_eq!(base.try_add(&F64(1.0)), Ok(Decimal(Decimal::TWO)));
1468 assert_eq!(
1469 base.try_add(&Decimal(Decimal::ONE)),
1470 Ok(Decimal(Decimal::TWO))
1471 );
1472 assert_eq!(
1473 base.try_add(&F32(f32::MAX)),
1474 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
1475 );
1476
1477 assert_eq!(
1478 base.try_add(&Bool(true)),
1479 Err(ValueError::NonNumericMathOperation {
1480 lhs: Decimal(base),
1481 operator: NumericBinaryOperator::Add,
1482 rhs: Bool(true),
1483 }
1484 .into()),
1485 );
1486 }
1487
1488 #[test]
1489 fn try_subtract() {
1490 let base = Decimal::ONE;
1491
1492 assert_eq!(base.try_subtract(&I8(1)), Ok(Decimal(Decimal::ZERO)));
1493 assert_eq!(base.try_subtract(&I32(1)), Ok(Decimal(Decimal::ZERO)));
1494 assert_eq!(base.try_subtract(&I64(1)), Ok(Decimal(Decimal::ZERO)));
1495 assert_eq!(base.try_subtract(&I128(1)), Ok(Decimal(Decimal::ZERO)));
1496 assert_eq!(base.try_subtract(&U8(1)), Ok(Decimal(Decimal::ZERO)));
1497 assert_eq!(base.try_subtract(&U16(1)), Ok(Decimal(Decimal::ZERO)));
1498 assert_eq!(base.try_subtract(&U32(1)), Ok(Decimal(Decimal::ZERO)));
1499 assert_eq!(base.try_subtract(&U64(1)), Ok(Decimal(Decimal::ZERO)));
1500 assert_eq!(base.try_subtract(&U128(1)), Ok(Decimal(Decimal::ZERO)));
1501 assert_eq!(base.try_subtract(&F32(1.0_f32)), Ok(Decimal(Decimal::ZERO)));
1502 assert_eq!(base.try_subtract(&F64(1.0)), Ok(Decimal(Decimal::ZERO)));
1503 assert_eq!(
1504 base.try_subtract(&Decimal(Decimal::ONE)),
1505 Ok(Decimal(Decimal::ZERO))
1506 );
1507 assert_eq!(
1508 (-base).try_subtract(&F32(f32::MIN)),
1509 Err(ValueError::FloatToDecimalConversionFailure(f32::MIN.into()).into())
1510 );
1511
1512 assert_eq!(
1513 base.try_subtract(&Bool(true)),
1514 Err(ValueError::NonNumericMathOperation {
1515 lhs: Decimal(base),
1516 operator: NumericBinaryOperator::Subtract,
1517 rhs: Bool(true),
1518 }
1519 .into()),
1520 );
1521 }
1522
1523 #[test]
1524 fn try_multiply() {
1525 let base = Decimal::ONE;
1526
1527 assert_eq!(base.try_multiply(&I8(1)), Ok(Decimal(Decimal::ONE)));
1528 assert_eq!(base.try_multiply(&I32(1)), Ok(Decimal(Decimal::ONE)));
1529 assert_eq!(base.try_multiply(&I64(1)), Ok(Decimal(Decimal::ONE)));
1530 assert_eq!(base.try_multiply(&I128(1)), Ok(Decimal(Decimal::ONE)));
1531 assert_eq!(base.try_multiply(&U8(1)), Ok(Decimal(Decimal::ONE)));
1532 assert_eq!(base.try_multiply(&U16(1)), Ok(Decimal(Decimal::ONE)));
1533 assert_eq!(base.try_multiply(&U32(1)), Ok(Decimal(Decimal::ONE)));
1534 assert_eq!(base.try_multiply(&U64(1)), Ok(Decimal(Decimal::ONE)));
1535 assert_eq!(base.try_multiply(&U128(1)), Ok(Decimal(Decimal::ONE)));
1536 assert_eq!(base.try_multiply(&F32(1.0_f32)), Ok(Decimal(Decimal::ONE)));
1537 assert_eq!(base.try_multiply(&F64(1.0)), Ok(Decimal(Decimal::ONE)));
1538 assert_eq!(
1539 base.try_multiply(&Decimal(Decimal::ONE)),
1540 Ok(Decimal(Decimal::ONE))
1541 );
1542 assert_eq!(
1543 Decimal::TWO.try_multiply(&F32(f32::MAX)),
1544 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
1545 );
1546
1547 assert_eq!(
1548 base.try_multiply(&Bool(true)),
1549 Err(ValueError::NonNumericMathOperation {
1550 lhs: Decimal(base),
1551 operator: NumericBinaryOperator::Multiply,
1552 rhs: Bool(true),
1553 }
1554 .into()),
1555 );
1556 }
1557
1558 #[test]
1559 fn try_divide() {
1560 let base = Decimal::ONE;
1561
1562 assert_eq!(base.try_divide(&I8(1)), Ok(Decimal(Decimal::ONE)));
1563 assert_eq!(base.try_divide(&I32(1)), Ok(Decimal(Decimal::ONE)));
1564 assert_eq!(base.try_divide(&I64(1)), Ok(Decimal(Decimal::ONE)));
1565 assert_eq!(base.try_divide(&I128(1)), Ok(Decimal(Decimal::ONE)));
1566 assert_eq!(base.try_divide(&U8(1)), Ok(Decimal(Decimal::ONE)));
1567 assert_eq!(base.try_divide(&U16(1)), Ok(Decimal(Decimal::ONE)));
1568 assert_eq!(base.try_divide(&U32(1)), Ok(Decimal(Decimal::ONE)));
1569 assert_eq!(base.try_divide(&U64(1)), Ok(Decimal(Decimal::ONE)));
1570 assert_eq!(base.try_divide(&U128(1)), Ok(Decimal(Decimal::ONE)));
1571 assert_eq!(base.try_divide(&F32(1.0_f32)), Ok(Decimal(Decimal::ONE)));
1572 assert_eq!(base.try_divide(&F64(1.0)), Ok(Decimal(Decimal::ONE)));
1573 assert_eq!(
1574 base.try_divide(&Decimal(Decimal::ONE)),
1575 Ok(Decimal(Decimal::ONE))
1576 );
1577 assert_eq!(
1578 base.try_divide(&F32(f32::MAX)),
1579 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
1580 );
1581
1582 assert_eq!(
1583 base.try_divide(&Bool(true)),
1584 Err(ValueError::NonNumericMathOperation {
1585 lhs: Decimal(base),
1586 operator: NumericBinaryOperator::Divide,
1587 rhs: Bool(true),
1588 }
1589 .into()),
1590 );
1591 }
1592
1593 #[test]
1594 fn try_modulo() {
1595 let base = Decimal::ONE;
1596
1597 assert_eq!(base.try_modulo(&I8(1)), Ok(Decimal(Decimal::ZERO)));
1598 assert_eq!(base.try_modulo(&I32(1)), Ok(Decimal(Decimal::ZERO)));
1599 assert_eq!(base.try_modulo(&I64(1)), Ok(Decimal(Decimal::ZERO)));
1600 assert_eq!(base.try_modulo(&I128(1)), Ok(Decimal(Decimal::ZERO)));
1601 assert_eq!(base.try_modulo(&U8(1)), Ok(Decimal(Decimal::ZERO)));
1602 assert_eq!(base.try_modulo(&U16(1)), Ok(Decimal(Decimal::ZERO)));
1603 assert_eq!(base.try_modulo(&U32(1)), Ok(Decimal(Decimal::ZERO)));
1604 assert_eq!(base.try_modulo(&U64(1)), Ok(Decimal(Decimal::ZERO)));
1605 assert_eq!(base.try_modulo(&U128(1)), Ok(Decimal(Decimal::ZERO)));
1606 assert_eq!(base.try_modulo(&F32(1.0_f32)), Ok(Decimal(Decimal::ZERO)));
1607 assert_eq!(base.try_modulo(&F64(1.0)), Ok(Decimal(Decimal::ZERO)));
1608 assert_eq!(
1609 base.try_modulo(&Decimal(Decimal::ONE)),
1610 Ok(Decimal(Decimal::ZERO))
1611 );
1612 assert_eq!(
1613 base.try_modulo(&F32(f32::INFINITY)),
1614 Err(ValueError::FloatToDecimalConversionFailure(f64::INFINITY).into())
1615 );
1616 assert_eq!(
1617 base.try_modulo(&F64(f64::INFINITY)),
1618 Err(ValueError::FloatToDecimalConversionFailure(f64::INFINITY).into())
1619 );
1620
1621 assert_eq!(
1622 base.try_modulo(&Bool(true)),
1623 Err(ValueError::NonNumericMathOperation {
1624 lhs: Decimal(base),
1625 operator: NumericBinaryOperator::Modulo,
1626 rhs: Bool(true),
1627 }
1628 .into()),
1629 );
1630 }
1631}