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