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