gluesql_core/data/value/binary_op/
decimal.rs

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        // try divide overflow
1176        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        // try modulo overflow
1289        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}