1use std::cmp::Ordering;
7use std::convert::TryFrom;
8use std::fmt::Debug;
9use std::fmt::Display;
10use std::fmt::Formatter;
11
12use crate::Error;
13use crate::error::Result;
14
15use ethnum::U256;
16use ethnum::i256;
17use num_traits::AsPrimitive;
18use num_traits::Bounded;
19use ordered_float::OrderedFloat;
20use serde::de;
21use serde::de::Deserialize;
22use serde::de::Deserializer;
23use serde::de::Visitor;
24use serde::ser::Serialize;
25use serde::ser::Serializer;
26
27const I128_POWERS_OF_10: [i128; 39] = [
29 1,
30 10,
31 100,
32 1000,
33 10000,
34 100000,
35 1000000,
36 10000000,
37 100000000,
38 1000000000,
39 10000000000,
40 100000000000,
41 1000000000000,
42 10000000000000,
43 100000000000000,
44 1000000000000000,
45 10000000000000000,
46 100000000000000000,
47 1000000000000000000,
48 10000000000000000000,
49 100000000000000000000,
50 1000000000000000000000,
51 10000000000000000000000,
52 100000000000000000000000,
53 1000000000000000000000000,
54 10000000000000000000000000,
55 100000000000000000000000000,
56 1000000000000000000000000000,
57 10000000000000000000000000000,
58 100000000000000000000000000000,
59 1000000000000000000000000000000,
60 10000000000000000000000000000000,
61 100000000000000000000000000000000,
62 1000000000000000000000000000000000,
63 10000000000000000000000000000000000,
64 100000000000000000000000000000000000,
65 1000000000000000000000000000000000000,
66 10000000000000000000000000000000000000,
67 100000000000000000000000000000000000000,
68];
69
70const LEADING_ZEROS: [&str; 38] = [
72 "",
73 "0",
74 "00",
75 "000",
76 "0000",
77 "00000",
78 "000000",
79 "0000000",
80 "00000000",
81 "000000000",
82 "0000000000",
83 "00000000000",
84 "000000000000",
85 "0000000000000",
86 "00000000000000",
87 "000000000000000",
88 "0000000000000000",
89 "00000000000000000",
90 "000000000000000000",
91 "0000000000000000000",
92 "00000000000000000000",
93 "000000000000000000000",
94 "0000000000000000000000",
95 "00000000000000000000000",
96 "000000000000000000000000",
97 "0000000000000000000000000",
98 "00000000000000000000000000",
99 "000000000000000000000000000",
100 "0000000000000000000000000000",
101 "00000000000000000000000000000",
102 "000000000000000000000000000000",
103 "0000000000000000000000000000000",
104 "00000000000000000000000000000000",
105 "000000000000000000000000000000000",
106 "0000000000000000000000000000000000",
107 "00000000000000000000000000000000000",
108 "000000000000000000000000000000000000",
109 "0000000000000000000000000000000000000",
110];
111
112const I128_SCALE: usize = 38;
113
114static I256_DIVIDE_SCALE: std::sync::LazyLock<i256> =
115 std::sync::LazyLock::new(|| i256::from(100000000000000000000000000000000000000_i128));
116
117#[derive(Debug, Clone)]
123pub struct Decimal64 {
124 pub scale: u8,
126 pub value: i64,
128}
129
130impl Decimal64 {
131 pub(crate) fn to_float64(&self) -> f64 {
136 let div = 10_f64.powi(self.scale as i32);
137 self.value as f64 / div
138 }
139}
140
141#[derive(Debug, Clone)]
147pub struct Decimal128 {
148 pub scale: u8,
150 pub value: i128,
152}
153
154impl Decimal128 {
155 pub(crate) fn to_float64(&self) -> f64 {
160 let div = 10_f64.powi(self.scale as i32);
161 self.value as f64 / div
162 }
163}
164
165#[derive(Debug, Clone)]
172pub struct Decimal256 {
173 pub scale: u8,
175 pub value: i256,
177}
178
179impl Decimal256 {
180 pub(crate) fn to_float64(&self) -> f64 {
185 let div = 10_f64.powi(self.scale as i32);
186 self.value.as_f64() / div
187 }
188}
189
190#[derive(Debug, Clone)]
201pub enum Number {
202 Int64(i64),
204 UInt64(u64),
206 Float64(f64),
208 Decimal64(Decimal64),
210 Decimal128(Decimal128),
212 Decimal256(Decimal256),
214}
215
216impl<'de> Deserialize<'de> for Number {
217 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
222 where
223 D: Deserializer<'de>,
224 {
225 struct NumberVisitor;
226
227 impl Visitor<'_> for NumberVisitor {
228 type Value = Number;
229
230 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
232 formatter.write_str("a number (int64, uint64, or float64)")
233 }
234
235 fn visit_i64<E>(self, v: i64) -> std::result::Result<Self::Value, E>
237 where
238 E: de::Error,
239 {
240 Ok(Number::Int64(v))
241 }
242
243 fn visit_u64<E>(self, v: u64) -> std::result::Result<Self::Value, E>
245 where
246 E: de::Error,
247 {
248 Ok(Number::UInt64(v))
249 }
250
251 fn visit_f64<E>(self, v: f64) -> std::result::Result<Self::Value, E>
253 where
254 E: de::Error,
255 {
256 Ok(Number::Float64(v))
257 }
258 }
259 deserializer.deserialize_any(NumberVisitor)
260 }
261}
262
263impl Serialize for Number {
264 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
269 where
270 S: Serializer,
271 {
272 match self {
273 Self::Int64(v) => serializer.serialize_i64(*v),
274 Self::UInt64(v) => serializer.serialize_u64(*v),
275 Self::Float64(v) => serializer.serialize_f64(*v),
276 Self::Decimal64(_) | Self::Decimal128(_) | Self::Decimal256(_) => {
277 let (value, scale) = match self {
278 Self::Decimal64(v) => (v.value as f64, v.scale as i32),
279 Self::Decimal128(v) => (v.value as f64, v.scale as i32),
280 Self::Decimal256(v) => (v.value.as_f64(), v.scale as i32),
281 _ => unreachable!(),
282 };
283 let scaled_value = value / 10f64.powi(scale);
284 serializer.serialize_f64(scaled_value)
285 }
286 }
287 }
288}
289
290impl Number {
291 pub(crate) fn as_i64(&self) -> Option<i64> {
298 match self {
299 Self::Int64(v) => Some(*v),
300 Self::UInt64(v) => {
301 if *v <= i64::MAX as u64 {
302 Some(*v as i64)
303 } else {
304 None
305 }
306 }
307 Self::Float64(v) => exact_float_to_int(*v),
308 Self::Decimal64(v) => exact_decimal_i128(v.value as i128, v.scale)
309 .and_then(|value| i64::try_from(value).ok()),
310 Self::Decimal128(v) => {
311 exact_decimal_i128(v.value, v.scale).and_then(|value| i64::try_from(value).ok())
312 }
313 Self::Decimal256(v) => {
314 exact_decimal_i256(v.value, v.scale).and_then(|value| i64::try_from(value).ok())
315 }
316 }
317 }
318
319 pub(crate) fn to_i128(&self) -> Option<i128> {
325 match self {
326 Self::Int64(v) => Some(*v as i128),
327 Self::UInt64(v) => Some(*v as i128),
328 Self::Float64(v) => round_float_to_int(*v),
329 Self::Decimal64(v) => round_decimal_i128(v.value as i128, v.scale),
330 Self::Decimal128(v) => round_decimal_i128(v.value, v.scale),
331 Self::Decimal256(v) => {
332 round_decimal_i256(v.value, v.scale).and_then(|value| i128::try_from(value).ok())
333 }
334 }
335 }
336
337 pub(crate) fn to_i64(&self) -> Option<i64> {
343 self.to_i128().and_then(|value| i64::try_from(value).ok())
344 }
345
346 pub(crate) fn as_f64(&self) -> f64 {
350 match self {
351 Self::Int64(v) => *v as f64,
352 Self::UInt64(v) => *v as f64,
353 Self::Float64(v) => *v,
354 Self::Decimal64(v) => v.to_float64(),
355 Self::Decimal128(v) => v.to_float64(),
356 Self::Decimal256(v) => v.to_float64(),
357 }
358 }
359
360 pub(crate) fn neg(&self) -> Result<Self> {
364 match self {
365 Self::Int64(v) => v
366 .checked_neg()
367 .map(Number::Int64)
368 .ok_or(Error::Message("Int64 overflow".to_string())),
369 Self::UInt64(v) => {
370 if let Ok(v) = i64::try_from(*v) {
371 v.checked_neg()
372 .map(Number::Int64)
373 .ok_or(Error::Message("Int64 overflow".to_string()))
374 } else {
375 Err(Error::Message("Int64 overflow".to_string()))
376 }
377 }
378 Self::Float64(v) => Ok(Self::Float64(*v * -1.0)),
379 Self::Decimal64(v) => {
380 let neg_dec = Decimal64 {
381 scale: v.scale,
382 value: -v.value,
383 };
384 Ok(Self::Decimal64(neg_dec))
385 }
386 Self::Decimal128(v) => {
387 let neg_dec = Decimal128 {
388 scale: v.scale,
389 value: -v.value,
390 };
391 Ok(Self::Decimal128(neg_dec))
392 }
393 Self::Decimal256(v) => {
394 let Some(neg_value) = v.value.checked_neg() else {
395 return Err(Error::Message("Decimal256 overflow".to_string()));
396 };
397 let neg_dec = Decimal256 {
398 scale: v.scale,
399 value: neg_value,
400 };
401 Ok(Self::Decimal256(neg_dec))
402 }
403 }
404 }
405
406 pub(crate) fn add(&self, other: Self) -> Result<Self> {
410 match (self, other) {
411 (Self::Int64(a), Self::Int64(b)) => a
412 .checked_add(b)
413 .map(Number::Int64)
414 .ok_or(Error::Message("Int64 overflow".to_string())),
415 (Self::UInt64(a), Self::UInt64(b)) => a
416 .checked_add(b)
417 .map(Number::UInt64)
418 .ok_or(Error::Message("UInt64 overflow".to_string())),
419 (Self::Int64(a), Self::UInt64(b)) => {
420 if *a < 0 {
421 a.checked_add(b as i64)
422 .map(Number::Int64)
423 .ok_or(Error::Message("Int64 overflow".to_string()))
424 } else {
425 (*a as u64)
426 .checked_add(b)
427 .map(Number::UInt64)
428 .ok_or(Error::Message("UInt64 overflow".to_string()))
429 }
430 }
431 (Self::UInt64(a), Self::Int64(b)) => {
432 if b < 0 {
433 (*a as i64)
434 .checked_add(b)
435 .map(Number::Int64)
436 .ok_or(Error::Message("Int64 overflow".to_string()))
437 } else {
438 a.checked_add(b as u64)
439 .map(Number::UInt64)
440 .ok_or(Error::Message("UInt64 overflow".to_string()))
441 }
442 }
443 (Self::Float64(a), Self::Float64(b)) => Ok(Self::Float64(a + b)),
444 (a, b) => {
445 let a_float = a.as_f64();
446 let b_float = b.as_f64();
447 Ok(Self::Float64(a_float + b_float))
448 }
449 }
450 }
451
452 pub(crate) fn sub(&self, other: Self) -> Result<Self> {
456 match (self, other) {
457 (Self::Int64(a), Self::Int64(b)) => a
458 .checked_sub(b)
459 .map(Number::Int64)
460 .ok_or(Error::Message("Int64 overflow".to_string())),
461 (Self::UInt64(a), Self::UInt64(b)) => (*a as i64)
462 .checked_sub(b as i64)
463 .map(Number::Int64)
464 .ok_or(Error::Message("UInt64 overflow".to_string())),
465 (Self::Int64(a), Self::UInt64(b)) => a
466 .checked_sub(b as i64)
467 .map(Number::Int64)
468 .ok_or(Error::Message("Int64 overflow".to_string())),
469 (Self::UInt64(a), Self::Int64(b)) => (*a as i64)
470 .checked_sub(b)
471 .map(Number::Int64)
472 .ok_or(Error::Message("Int64 overflow".to_string())),
473 (Self::Float64(a), Self::Float64(b)) => Ok(Self::Float64(a - b)),
474 (a, b) => {
475 let a_float = a.as_f64();
476 let b_float = b.as_f64();
477 Ok(Self::Float64(a_float - b_float))
478 }
479 }
480 }
481
482 pub(crate) fn mul(&self, other: Self) -> Result<Self> {
486 match (self, other) {
487 (Self::Int64(a), Self::Int64(b)) => a
488 .checked_mul(b)
489 .map(Number::Int64)
490 .ok_or(Error::Message("Int64 overflow".to_string())),
491 (Self::UInt64(a), Self::UInt64(b)) => a
492 .checked_mul(b)
493 .map(Number::UInt64)
494 .ok_or(Error::Message("UInt64 overflow".to_string())),
495 (Self::Int64(a), Self::UInt64(b)) => {
496 if *a < 0 {
497 a.checked_mul(b as i64)
498 .map(Number::Int64)
499 .ok_or(Error::Message("Int64 overflow".to_string()))
500 } else {
501 (*a as u64)
502 .checked_mul(b)
503 .map(Number::UInt64)
504 .ok_or(Error::Message("UInt64 overflow".to_string()))
505 }
506 }
507 (Self::UInt64(a), Self::Int64(b)) => {
508 if b < 0 {
509 (*a as i64)
510 .checked_mul(b)
511 .map(Number::Int64)
512 .ok_or(Error::Message("Int64 overflow".to_string()))
513 } else {
514 a.checked_mul(b as u64)
515 .map(Number::UInt64)
516 .ok_or(Error::Message("UInt64 overflow".to_string()))
517 }
518 }
519 (Self::Float64(a), Self::Float64(b)) => Ok(Self::Float64(a * b)),
520 (a, b) => {
521 let a_float = a.as_f64();
522 let b_float = b.as_f64();
523 Ok(Self::Float64(a_float * b_float))
524 }
525 }
526 }
527
528 pub(crate) fn div(&self, other: Self) -> Result<Self> {
532 let a_float = self.as_f64();
533 let b_float = other.as_f64();
534 if b_float == 0.0 {
535 return Err(Error::Message("Division by zero".to_string()));
536 }
537 Ok(Self::Float64(a_float / b_float))
538 }
539
540 pub(crate) fn rem(&self, other: Self) -> Result<Self> {
544 match (self, other) {
545 (Self::Int64(a), Self::Int64(b)) => {
546 if b == 0 {
547 return Err(Error::Message("Division by zero".to_string()));
548 }
549 a.checked_rem(b)
550 .map(Number::Int64)
551 .ok_or(Error::Message("Int64 overflow".to_string()))
552 }
553 (Self::UInt64(a), Self::UInt64(b)) => {
554 if b == 0 {
555 return Err(Error::Message("Division by zero".to_string()));
556 }
557 a.checked_rem(b)
558 .map(Number::UInt64)
559 .ok_or(Error::Message("UInt64 overflow".to_string()))
560 }
561 (Self::Int64(a), Self::UInt64(b)) => {
562 if b == 0 {
563 return Err(Error::Message("Division by zero".to_string()));
564 }
565 if *a < 0 {
566 a.checked_rem(b as i64)
567 .map(Number::Int64)
568 .ok_or(Error::Message("Int64 overflow".to_string()))
569 } else {
570 (*a as u64)
571 .checked_rem(b)
572 .map(Number::UInt64)
573 .ok_or(Error::Message("UInt64 overflow".to_string()))
574 }
575 }
576 (Self::UInt64(a), Self::Int64(b)) => {
577 if b == 0 {
578 return Err(Error::Message("Division by zero".to_string()));
579 }
580 if b < 0 {
581 (*a as i64)
582 .checked_rem(b)
583 .map(Number::Int64)
584 .ok_or(Error::Message("Int64 overflow".to_string()))
585 } else {
586 a.checked_rem(b as u64)
587 .map(Number::UInt64)
588 .ok_or(Error::Message("UInt64 overflow".to_string()))
589 }
590 }
591 (Self::Float64(a), Self::Float64(b)) => {
592 if b == 0.0 {
593 return Err(Error::Message("Division by zero".to_string()));
594 }
595 Ok(Self::Float64(a % b))
596 }
597 (a, b) => {
598 let a_float = a.as_f64();
599 let b_float = b.as_f64();
600 if b_float == 0.0 {
601 return Err(Error::Message("Division by zero".to_string()));
602 }
603 Ok(Self::Float64(a_float % b_float))
604 }
605 }
606 }
607}
608
609fn exact_float_to_int<T>(value: f64) -> Option<T>
610where
611 T: Bounded + AsPrimitive<f64>,
612 f64: AsPrimitive<T>,
613{
614 if !value.is_finite() || value.fract() != 0.0 {
615 return None;
616 }
617
618 if fits_float_target_range::<T>(value) {
619 Some(value.as_())
620 } else {
621 None
622 }
623}
624
625fn round_float_to_int<T>(value: f64) -> Option<T>
626where
627 T: Bounded + AsPrimitive<f64>,
628 f64: AsPrimitive<T>,
629{
630 if !value.is_finite() {
631 return None;
632 }
633
634 let rounded = value.round();
635 if fits_float_target_range::<T>(rounded) {
636 Some(rounded.as_())
637 } else {
638 None
639 }
640}
641
642#[inline]
645fn fits_float_target_range<T>(value: f64) -> bool
646where
647 T: Bounded + AsPrimitive<f64>,
648{
649 let lower = T::min_value().as_();
650 let upper_exclusive = if lower < 0.0 {
651 -lower
652 } else {
653 T::max_value().as_() + 1.0
654 };
655
656 value >= lower && value < upper_exclusive
657}
658
659fn exact_decimal_i128(value: i128, scale: u8) -> Option<i128> {
660 if scale == 0 {
661 return Some(value);
662 }
663
664 let Some(divisor) = I128_POWERS_OF_10.get(scale as usize) else {
665 return if value == 0 { Some(0) } else { None };
666 };
667
668 if value % divisor == 0 {
669 Some(value / divisor)
670 } else {
671 None
672 }
673}
674
675fn round_decimal_i128(value: i128, scale: u8) -> Option<i128> {
676 if scale == 0 {
677 return Some(value);
678 }
679
680 let Some(divisor) = I128_POWERS_OF_10.get(scale as usize) else {
681 return Some(0);
683 };
684
685 let quotient = value / divisor;
686 let remainder = value % divisor;
687 let abs_remainder = remainder.unsigned_abs();
688 let divisor = *divisor as u128;
689 let round_up = abs_remainder >= divisor - abs_remainder;
690
691 if !round_up {
692 Some(quotient)
693 } else if value >= 0 {
694 quotient.checked_add(1)
695 } else {
696 quotient.checked_sub(1)
697 }
698}
699
700#[inline]
701fn signed_i256_from_abs(abs: U256, negative: bool) -> Option<i256> {
702 let value = i256::try_from(abs).ok()?;
703 if negative {
704 i256::ZERO.checked_sub(value)
705 } else {
706 Some(value)
707 }
708}
709
710fn exact_decimal_i256(value: i256, scale: u8) -> Option<i256> {
711 if scale == 0 {
712 return Some(value);
713 }
714
715 let Some(divisor) = U256::new(10).checked_pow(scale as u32) else {
716 return if value == i256::ZERO {
717 Some(i256::ZERO)
718 } else {
719 None
720 };
721 };
722
723 let negative = value < i256::ZERO;
724 let abs_value = value.unsigned_abs();
725 let quotient = abs_value / divisor;
726 let remainder = abs_value % divisor;
727 if remainder != U256::ZERO {
728 return None;
729 }
730
731 signed_i256_from_abs(quotient, negative)
732}
733
734fn round_decimal_i256(value: i256, scale: u8) -> Option<i256> {
735 if scale == 0 {
736 return Some(value);
737 }
738
739 let Some(divisor) = U256::new(10).checked_pow(scale as u32) else {
740 return Some(i256::ZERO);
742 };
743
744 let negative = value < i256::ZERO;
745 let abs_value = value.unsigned_abs();
746 let quotient = abs_value / divisor;
747 let remainder = abs_value % divisor;
748 let round_up = remainder >= divisor - remainder;
749 let rounded = if round_up {
750 quotient.checked_add(U256::new(1))?
751 } else {
752 quotient
753 };
754
755 signed_i256_from_abs(rounded, negative)
756}
757
758impl Default for Number {
759 #[inline]
763 fn default() -> Self {
764 Self::UInt64(0)
765 }
766}
767
768impl PartialEq for Number {
769 #[inline]
773 fn eq(&self, other: &Self) -> bool {
774 self.cmp(other) == Ordering::Equal
775 }
776}
777
778impl PartialEq<&Self> for Number {
779 #[inline]
783 fn eq(&self, other: &&Self) -> bool {
784 self.eq(*other)
785 }
786}
787
788impl PartialEq<Number> for &Number {
789 #[inline]
793 fn eq(&self, other: &Number) -> bool {
794 (*self).eq(other)
795 }
796}
797
798impl Eq for Number {}
799
800impl PartialOrd for Number {
801 #[inline]
805 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
806 Some(self.cmp(other))
807 }
808}
809
810impl PartialOrd<&Self> for Number {
811 #[inline]
815 fn partial_cmp(&self, other: &&Self) -> Option<Ordering> {
816 self.partial_cmp(*other)
817 }
818}
819
820impl PartialOrd<Number> for &Number {
821 #[inline]
825 fn partial_cmp(&self, other: &Number) -> Option<Ordering> {
826 (*self).partial_cmp(other)
827 }
828}
829
830impl Ord for Number {
831 #[inline]
840 fn cmp(&self, other: &Self) -> Ordering {
841 match (self, other) {
842 (Self::Int64(l), Self::Int64(r)) => l.cmp(r),
844 (Self::UInt64(l), Self::UInt64(r)) => l.cmp(r),
845 (Self::Float64(l), Self::Float64(r)) => OrderedFloat(*l).cmp(&OrderedFloat(*r)),
846 (Self::Decimal64(l), Self::Decimal64(r)) => {
847 if l.scale == r.scale {
849 l.value.cmp(&r.value)
850 } else {
851 if let Some((l_val, r_val)) =
853 adjust_decimal_scales(l.value as i128, l.scale, r.value as i128, r.scale)
854 {
855 l_val.cmp(&r_val)
856 } else {
857 let l = OrderedFloat(self.as_f64());
858 let r = OrderedFloat(other.as_f64());
859 l.cmp(&r)
860 }
861 }
862 }
863 (Self::Decimal128(l), Self::Decimal128(r)) => {
864 if l.scale == r.scale {
866 l.value.cmp(&r.value)
867 } else {
868 if let Some((l_val, r_val)) =
870 adjust_decimal_scales(l.value, l.scale, r.value, r.scale)
871 {
872 l_val.cmp(&r_val)
873 } else {
874 let l = OrderedFloat(self.as_f64());
875 let r = OrderedFloat(other.as_f64());
876 l.cmp(&r)
877 }
878 }
879 }
880 (Self::Decimal256(l), Self::Decimal256(r)) => {
881 if l.scale == r.scale {
883 l.value.cmp(&r.value)
884 } else {
885 let scale_diff = l.scale as i32 - r.scale as i32;
887 if scale_diff > 0 {
888 let scale_factor = i256::from(10).pow(scale_diff as u32);
890 if let Some(r_val) = r.value.checked_mul(scale_factor) {
891 return l.value.cmp(&r_val);
892 }
893 } else {
894 let scale_factor = i256::from(10).pow((-scale_diff) as u32);
896 if let Some(l_val) = l.value.checked_mul(scale_factor) {
897 return l_val.cmp(&r.value);
898 }
899 }
900 let l = OrderedFloat(self.as_f64());
902 let r = OrderedFloat(other.as_f64());
903 l.cmp(&r)
904 }
905 }
906
907 (Self::Int64(l), Self::UInt64(r)) => {
909 if *l < 0 {
910 Ordering::Less
911 } else {
912 (*l as u64).cmp(r)
913 }
914 }
915 (Self::UInt64(l), Self::Int64(r)) => {
916 if *r < 0 {
917 Ordering::Greater
918 } else {
919 l.cmp(&(*r as u64))
920 }
921 }
922
923 (Self::Decimal64(_), Self::Int64(r)) => {
925 let r_decimal = Decimal64 {
927 scale: 0,
928 value: *r,
929 };
930 self.cmp(&Self::Decimal64(r_decimal))
931 }
932 (Self::Int64(l), Self::Decimal64(_)) => {
933 let l_decimal = Decimal64 {
935 scale: 0,
936 value: *l,
937 };
938 Self::Decimal64(l_decimal).cmp(other)
939 }
940 (Self::Decimal64(_), Self::UInt64(r)) => {
941 if *r <= i64::MAX as u64 {
943 let r_decimal = Decimal64 {
945 scale: 0,
946 value: *r as i64,
947 };
948 self.cmp(&Self::Decimal64(r_decimal))
949 } else {
950 let r_decimal = Decimal128 {
952 scale: 0,
953 value: *r as i128,
954 };
955 self.cmp(&Self::Decimal128(r_decimal))
956 }
957 }
958 (Self::UInt64(l), Self::Decimal64(_)) => {
959 if *l <= i64::MAX as u64 {
961 let l_decimal = Decimal64 {
963 scale: 0,
964 value: *l as i64,
965 };
966 Self::Decimal64(l_decimal).cmp(other)
967 } else {
968 let l_decimal = Decimal128 {
970 scale: 0,
971 value: *l as i128,
972 };
973 Self::Decimal128(l_decimal).cmp(other)
974 }
975 }
976
977 (Self::Decimal128(_), Self::Int64(r)) => {
979 let r_decimal = Decimal128 {
981 scale: 0,
982 value: *r as i128,
983 };
984 self.cmp(&Self::Decimal128(r_decimal))
985 }
986 (Self::Int64(l), Self::Decimal128(_)) => {
987 let l_decimal = Decimal128 {
989 scale: 0,
990 value: *l as i128,
991 };
992 Self::Decimal128(l_decimal).cmp(other)
993 }
994 (Self::Decimal128(_), Self::UInt64(r)) => {
995 let r_decimal = Decimal128 {
997 scale: 0,
998 value: *r as i128,
999 };
1000 self.cmp(&Self::Decimal128(r_decimal))
1001 }
1002 (Self::UInt64(l), Self::Decimal128(_)) => {
1003 let l_decimal = Decimal128 {
1005 scale: 0,
1006 value: *l as i128,
1007 };
1008 Self::Decimal128(l_decimal).cmp(other)
1009 }
1010
1011 (Self::Decimal256(_), Self::Int64(r)) => {
1013 let r_decimal = Decimal256 {
1015 scale: 0,
1016 value: i256::from(*r),
1017 };
1018 self.cmp(&Self::Decimal256(r_decimal))
1019 }
1020 (Self::Int64(l), Self::Decimal256(_)) => {
1021 let l_decimal = Decimal256 {
1023 scale: 0,
1024 value: i256::from(*l),
1025 };
1026 Self::Decimal256(l_decimal).cmp(other)
1027 }
1028 (Self::Decimal256(_), Self::UInt64(r)) => {
1029 let r_decimal = Decimal256 {
1031 scale: 0,
1032 value: i256::from(*r),
1033 };
1034 self.cmp(&Self::Decimal256(r_decimal))
1035 }
1036 (Self::UInt64(l), Self::Decimal256(_)) => {
1037 let l_decimal = Decimal256 {
1039 scale: 0,
1040 value: i256::from(*l),
1041 };
1042 Self::Decimal256(l_decimal).cmp(other)
1043 }
1044
1045 (Self::Decimal64(l), Self::Decimal128(_)) => {
1047 let l_decimal = Decimal128 {
1049 scale: l.scale,
1050 value: l.value as i128,
1051 };
1052 Self::Decimal128(l_decimal).cmp(other)
1053 }
1054 (Self::Decimal128(_), Self::Decimal64(r)) => {
1055 let r_decimal = Decimal128 {
1057 scale: r.scale,
1058 value: r.value as i128,
1059 };
1060 self.cmp(&Self::Decimal128(r_decimal))
1061 }
1062 (Self::Decimal64(l), Self::Decimal256(_)) => {
1063 let l_decimal = Decimal256 {
1065 scale: l.scale,
1066 value: i256::from(l.value),
1067 };
1068 Self::Decimal256(l_decimal).cmp(other)
1069 }
1070 (Self::Decimal256(_), Self::Decimal64(r)) => {
1071 let r_decimal = Decimal256 {
1073 scale: r.scale,
1074 value: i256::from(r.value),
1075 };
1076 self.cmp(&Self::Decimal256(r_decimal))
1077 }
1078 (Self::Decimal128(l), Self::Decimal256(_)) => {
1079 let l_decimal = Decimal256 {
1081 scale: l.scale,
1082 value: i256::from(l.value),
1083 };
1084 Self::Decimal256(l_decimal).cmp(other)
1085 }
1086 (Self::Decimal256(_), Self::Decimal128(r)) => {
1087 let r_decimal = Decimal256 {
1089 scale: r.scale,
1090 value: i256::from(r.value),
1091 };
1092 self.cmp(&Self::Decimal256(r_decimal))
1093 }
1094
1095 (_, _) => {
1097 let l = OrderedFloat(self.as_f64());
1098 let r = OrderedFloat(other.as_f64());
1099 l.cmp(&r)
1100 }
1101 }
1102 }
1103}
1104
1105fn adjust_decimal_scales(
1110 l_val: i128,
1111 l_scale: u8,
1112 r_val: i128,
1113 r_scale: u8,
1114) -> Option<(i128, i128)> {
1115 let scale_diff = l_scale as i32 - r_scale as i32;
1116
1117 match scale_diff.cmp(&0) {
1118 Ordering::Greater => {
1119 let scale_factor = 10_i128.pow(scale_diff as u32);
1121 let r_val = r_val.checked_mul(scale_factor)?;
1122 Some((l_val, r_val))
1123 }
1124 Ordering::Less => {
1125 let scale_factor = 10_i128.pow((-scale_diff) as u32);
1127 let l_val = l_val.checked_mul(scale_factor)?;
1128 Some((l_val, r_val))
1129 }
1130 Ordering::Equal => {
1131 Some((l_val, r_val))
1133 }
1134 }
1135}
1136
1137impl Display for Number {
1138 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1142 match self {
1143 Self::Int64(v) => {
1144 let mut buffer = itoa::Buffer::new();
1145 let s = buffer.format(*v);
1146 write!(f, "{}", s)
1147 }
1148 Self::UInt64(v) => {
1149 let mut buffer = itoa::Buffer::new();
1150 let s = buffer.format(*v);
1151 write!(f, "{}", s)
1152 }
1153 Self::Float64(v) => {
1154 let mut buffer = zmij::Buffer::new();
1155 let s = buffer.format(*v);
1156 write!(f, "{}", s)
1157 }
1158 Self::Decimal64(v) => format_decimal_i128(f, v.value as i128, v.scale as usize),
1159 Self::Decimal128(v) => format_decimal_i128(f, v.value, v.scale as usize),
1160 Self::Decimal256(v) => format_decimal_i256(f, v.value, v.scale as usize),
1161 }
1162 }
1163}
1164
1165fn format_decimal_i128(
1173 f: &mut impl std::fmt::Write,
1174 value: i128,
1175 scale: usize,
1176) -> std::fmt::Result {
1177 let mut itoa_buf = itoa::Buffer::new();
1178 if scale == 0 {
1179 f.write_str(itoa_buf.format(value))
1180 } else {
1181 let value = if value < 0 {
1183 f.write_str("-")?;
1184 -value
1185 } else {
1186 value
1187 };
1188 let pow_scale = I128_POWERS_OF_10[scale];
1189 let integer_part = value / pow_scale;
1191 f.write_str(itoa_buf.format(integer_part))?;
1192 f.write_str(".")?;
1193
1194 let fractional_part = (value % pow_scale).abs();
1196 let fractional_str = itoa_buf.format(fractional_part);
1197
1198 let leading_zeros_count = scale - fractional_str.len();
1199 if leading_zeros_count > 0 {
1200 let zeros = LEADING_ZEROS[leading_zeros_count];
1201 f.write_str(zeros)?;
1202 }
1203 f.write_str(fractional_str)
1204 }
1205}
1206
1207fn format_decimal_i256(
1212 f: &mut impl std::fmt::Write,
1213 value: i256,
1214 scale: usize,
1215) -> std::fmt::Result {
1216 let value = if value < i256::ZERO {
1218 f.write_str("-")?;
1219 -value
1220 } else {
1221 value
1222 };
1223
1224 let high_part = (value / *I256_DIVIDE_SCALE).as_i128();
1226 let low_part = (value % *I256_DIVIDE_SCALE).as_i128();
1227 let mut itoa_buf = itoa::Buffer::new();
1228
1229 if scale == 0 {
1231 if high_part > 0 {
1232 f.write_str(itoa_buf.format(high_part))?;
1234
1235 let low_str = itoa_buf.format(low_part);
1237 let zeros_count = I128_SCALE - low_str.len();
1238 if zeros_count > 0 {
1239 let zeros = LEADING_ZEROS[zeros_count];
1240 f.write_str(zeros)?;
1241 }
1242 f.write_str(low_str)
1243 } else {
1244 f.write_str(itoa_buf.format(low_part))
1246 }
1247 }
1248 else if scale >= I128_SCALE {
1250 let high_scale = scale - I128_SCALE;
1252 let pow_scale = I128_POWERS_OF_10[high_scale];
1253
1254 let int_part = high_part / pow_scale;
1256 f.write_str(itoa_buf.format(int_part))?;
1257 f.write_str(".")?;
1258
1259 if high_scale > 0 {
1261 let high_frac_part = high_part % pow_scale;
1262 let high_frac_str = itoa_buf.format(high_frac_part);
1263
1264 let high_zeros_count = high_scale - high_frac_str.len();
1266 if high_zeros_count > 0 {
1267 let zeros = LEADING_ZEROS[high_zeros_count];
1268 f.write_str(zeros)?;
1269 }
1270 f.write_str(high_frac_str)?;
1271 }
1272
1273 let mut low_buf = itoa::Buffer::new();
1275 let low_frac_str = low_buf.format(low_part);
1276 let low_zeros_count = I128_SCALE - low_frac_str.len();
1277 if low_zeros_count > 0 {
1278 let low_zeros = LEADING_ZEROS[low_zeros_count];
1279 f.write_str(low_zeros)?;
1280 }
1281 f.write_str(low_frac_str)
1282 }
1283 else {
1285 if high_part > 0 {
1287 f.write_str(itoa_buf.format(high_part))?;
1288 }
1289 let pow_scale = I128_POWERS_OF_10[scale];
1290
1291 let int_part = low_part / pow_scale;
1293 let int_str = itoa_buf.format(int_part);
1294
1295 if high_part > 0 {
1297 let int_zeros_count = I128_SCALE - scale - int_str.len();
1298 if int_zeros_count > 0 {
1299 let int_zeros = LEADING_ZEROS[int_zeros_count];
1300 f.write_str(int_zeros)?;
1301 }
1302 }
1303 f.write_str(int_str)?;
1304 f.write_str(".")?;
1305
1306 let frac_part = low_part % pow_scale;
1308 let mut frac_buf = itoa::Buffer::new();
1309 let frac_str = frac_buf.format(frac_part);
1310
1311 let frac_zeros_count = scale - frac_str.len();
1312 if frac_zeros_count > 0 {
1313 let frac_zeros = LEADING_ZEROS[frac_zeros_count];
1314 f.write_str(frac_zeros)?;
1315 }
1316 f.write_str(frac_str)
1317 }
1318}
1319
1320#[cfg(test)]
1321mod tests {
1322 use super::*;
1323 use std::cmp::Ordering;
1324
1325 #[test]
1326 fn test_number_comparison() {
1327 assert_eq!(Number::Int64(10).cmp(&Number::Int64(5)), Ordering::Greater);
1329 assert_eq!(Number::Int64(5).cmp(&Number::Int64(10)), Ordering::Less);
1330 assert_eq!(Number::Int64(5).cmp(&Number::Int64(5)), Ordering::Equal);
1331
1332 assert_eq!(
1333 Number::UInt64(10).cmp(&Number::UInt64(5)),
1334 Ordering::Greater
1335 );
1336 assert_eq!(Number::UInt64(5).cmp(&Number::UInt64(10)), Ordering::Less);
1337 assert_eq!(Number::UInt64(5).cmp(&Number::UInt64(5)), Ordering::Equal);
1338
1339 assert_eq!(
1340 Number::Float64(10.0).cmp(&Number::Float64(5.0)),
1341 Ordering::Greater
1342 );
1343 assert_eq!(
1344 Number::Float64(5.0).cmp(&Number::Float64(10.0)),
1345 Ordering::Less
1346 );
1347 assert_eq!(
1348 Number::Float64(5.0).cmp(&Number::Float64(5.0)),
1349 Ordering::Equal
1350 );
1351
1352 assert_eq!(Number::Int64(10).cmp(&Number::UInt64(5)), Ordering::Greater);
1354 assert_eq!(Number::Int64(5).cmp(&Number::UInt64(10)), Ordering::Less);
1355 assert_eq!(Number::Int64(5).cmp(&Number::UInt64(5)), Ordering::Equal);
1356 assert_eq!(Number::Int64(-5).cmp(&Number::UInt64(5)), Ordering::Less);
1357
1358 assert_eq!(Number::UInt64(10).cmp(&Number::Int64(5)), Ordering::Greater);
1359 assert_eq!(Number::UInt64(5).cmp(&Number::Int64(10)), Ordering::Less);
1360 assert_eq!(Number::UInt64(5).cmp(&Number::Int64(5)), Ordering::Equal);
1361 assert_eq!(Number::UInt64(5).cmp(&Number::Int64(-5)), Ordering::Greater);
1362
1363 let d1 = Decimal64 {
1365 scale: 2,
1366 value: 1234,
1367 }; let d2 = Decimal64 {
1369 scale: 2,
1370 value: 5678,
1371 }; assert_eq!(
1373 Number::Decimal64(d1.clone()).cmp(&Number::Decimal64(d2.clone())),
1374 Ordering::Less
1375 );
1376 assert_eq!(
1377 Number::Decimal64(d2).cmp(&Number::Decimal64(d1.clone())),
1378 Ordering::Greater
1379 );
1380 assert_eq!(
1381 Number::Decimal64(d1.clone()).cmp(&Number::Decimal64(d1.clone())),
1382 Ordering::Equal
1383 );
1384
1385 let d3 = Decimal64 {
1387 scale: 3,
1388 value: 12340,
1389 }; assert_eq!(
1391 Number::Decimal64(d1.clone()).cmp(&Number::Decimal64(d3)),
1392 Ordering::Equal
1393 );
1394
1395 let d4 = Decimal64 {
1396 scale: 1,
1397 value: 123,
1398 }; assert_eq!(
1400 Number::Decimal64(d1).cmp(&Number::Decimal64(d4)),
1401 Ordering::Greater
1402 );
1403
1404 let d5 = Decimal128 {
1406 scale: 2,
1407 value: 1234,
1408 }; let d6 = Decimal128 {
1410 scale: 2,
1411 value: 5678,
1412 }; assert_eq!(
1414 Number::Decimal128(d5).cmp(&Number::Decimal128(d6)),
1415 Ordering::Less
1416 );
1417
1418 let d7 = Decimal256 {
1420 scale: 2,
1421 value: i256::from(1234),
1422 }; let d8 = Decimal256 {
1424 scale: 2,
1425 value: i256::from(5678),
1426 }; assert_eq!(
1428 Number::Decimal256(d7).cmp(&Number::Decimal256(d8)),
1429 Ordering::Less
1430 );
1431
1432 assert_eq!(
1434 Number::Int64(12).cmp(&Number::Decimal64(Decimal64 {
1435 scale: 0,
1436 value: 12
1437 })),
1438 Ordering::Equal
1439 );
1440 assert_eq!(
1441 Number::Int64(12).cmp(&Number::Decimal64(Decimal64 {
1442 scale: 1,
1443 value: 120
1444 })),
1445 Ordering::Equal
1446 );
1447 assert_eq!(
1448 Number::Int64(12).cmp(&Number::Decimal64(Decimal64 {
1449 scale: 1,
1450 value: 121
1451 })),
1452 Ordering::Less
1453 );
1454 assert_eq!(
1455 Number::Int64(12).cmp(&Number::Decimal64(Decimal64 {
1456 scale: 1,
1457 value: 119
1458 })),
1459 Ordering::Greater
1460 );
1461
1462 assert_eq!(
1464 Number::UInt64(12).cmp(&Number::Decimal64(Decimal64 {
1465 scale: 0,
1466 value: 12
1467 })),
1468 Ordering::Equal
1469 );
1470 assert_eq!(
1471 Number::UInt64(12).cmp(&Number::Decimal64(Decimal64 {
1472 scale: 1,
1473 value: 120
1474 })),
1475 Ordering::Equal
1476 );
1477
1478 assert_eq!(
1480 Number::Float64(12.34).cmp(&Number::Decimal64(Decimal64 {
1481 scale: 2,
1482 value: 1234
1483 })),
1484 Ordering::Equal
1485 );
1486 assert_eq!(
1487 Number::Float64(12.34).cmp(&Number::Decimal64(Decimal64 {
1488 scale: 2,
1489 value: 1235
1490 })),
1491 Ordering::Less
1492 );
1493
1494 assert_eq!(
1497 Number::Decimal64(Decimal64 {
1498 scale: 2,
1499 value: 1234
1500 })
1501 .cmp(&Number::Decimal128(Decimal128 {
1502 scale: 2,
1503 value: 1234
1504 })),
1505 Ordering::Equal
1506 );
1507 assert_eq!(
1508 Number::Decimal64(Decimal64 {
1509 scale: 2,
1510 value: 1234
1511 })
1512 .cmp(&Number::Decimal128(Decimal128 {
1513 scale: 2,
1514 value: 5678
1515 })),
1516 Ordering::Less
1517 );
1518
1519 assert_eq!(
1521 Number::Decimal64(Decimal64 {
1522 scale: 2,
1523 value: 1234
1524 })
1525 .cmp(&Number::Decimal256(Decimal256 {
1526 scale: 2,
1527 value: i256::from(1234)
1528 })),
1529 Ordering::Equal
1530 );
1531
1532 assert_eq!(
1534 Number::Decimal128(Decimal128 {
1535 scale: 2,
1536 value: 1234
1537 })
1538 .cmp(&Number::Decimal256(Decimal256 {
1539 scale: 2,
1540 value: i256::from(1234)
1541 })),
1542 Ordering::Equal
1543 );
1544
1545 assert_eq!(
1547 Number::Decimal64(Decimal64 {
1548 scale: 2,
1549 value: 1234
1550 })
1551 .cmp(&Number::Decimal128(Decimal128 {
1552 scale: 3,
1553 value: 12340
1554 })),
1555 Ordering::Equal
1556 );
1557
1558 let large_int = i64::MAX;
1561 let large_uint = u64::MAX;
1562 let large_decimal = Decimal128 {
1563 scale: 0,
1564 value: i128::from(large_int),
1565 };
1566
1567 assert_eq!(
1568 Number::Int64(large_int).cmp(&Number::Decimal128(large_decimal.clone())),
1569 Ordering::Equal
1570 );
1571 assert_eq!(
1572 Number::Decimal128(large_decimal.clone()).cmp(&Number::Int64(large_int)),
1573 Ordering::Equal
1574 );
1575
1576 assert_eq!(
1577 Number::UInt64(large_uint).cmp(&Number::Decimal128(large_decimal.clone())),
1578 Ordering::Greater
1579 );
1580 assert_eq!(
1581 Number::Decimal128(large_decimal).cmp(&Number::UInt64(large_uint)),
1582 Ordering::Less
1583 );
1584
1585 let neg_int = -100;
1587 let neg_decimal = Decimal64 {
1588 scale: 0,
1589 value: -100,
1590 };
1591
1592 assert_eq!(
1593 Number::Int64(neg_int).cmp(&Number::Decimal64(neg_decimal.clone())),
1594 Ordering::Equal
1595 );
1596 assert_eq!(
1597 Number::Decimal64(neg_decimal).cmp(&Number::UInt64(100)),
1598 Ordering::Less
1599 );
1600
1601 assert_eq!(Number::Int64(0).cmp(&Number::UInt64(0)), Ordering::Equal);
1603 assert_eq!(
1604 Number::Int64(0).cmp(&Number::Decimal64(Decimal64 { scale: 0, value: 0 })),
1605 Ordering::Equal
1606 );
1607 assert_eq!(
1608 Number::Int64(0).cmp(&Number::Decimal64(Decimal64 { scale: 5, value: 0 })),
1609 Ordering::Equal
1610 );
1611 }
1612
1613 #[test]
1614 fn test_exact_integer_casts() {
1615 let decimal64 = Number::Decimal64(Decimal64 {
1616 scale: 1,
1617 value: 1230,
1618 });
1619 assert_eq!(decimal64.as_i64(), Some(123));
1620
1621 let decimal128 = Number::Decimal128(Decimal128 {
1622 scale: 1,
1623 value: 1230,
1624 });
1625 assert_eq!(decimal128.as_i64(), Some(123));
1626
1627 let negative_decimal128 = Number::Decimal128(Decimal128 {
1628 scale: 1,
1629 value: -1230,
1630 });
1631 assert_eq!(negative_decimal128.as_i64(), Some(-123));
1632
1633 let non_integer_decimal64 = Number::Decimal64(Decimal64 {
1634 scale: 1,
1635 value: 1234,
1636 });
1637 assert_eq!(non_integer_decimal64.as_i64(), None);
1638
1639 let decimal256 = Number::Decimal256(Decimal256 {
1640 scale: 1,
1641 value: i256::from(1230),
1642 });
1643 assert_eq!(decimal256.as_i64(), Some(123));
1644
1645 let float = Number::Float64(123.0);
1646 assert_eq!(float.as_i64(), Some(123));
1647
1648 let non_integer_float = Number::Float64(123.1);
1649 assert_eq!(non_integer_float.as_i64(), None);
1650 }
1651
1652 #[test]
1653 fn test_rounded_integer_casts() {
1654 let decimal128 = Number::Decimal128(Decimal128 {
1655 scale: 1,
1656 value: 1235,
1657 });
1658 assert_eq!(decimal128.to_i128(), Some(124));
1659 assert_eq!(decimal128.to_i64(), Some(124));
1660
1661 let negative_decimal128 = Number::Decimal128(Decimal128 {
1662 scale: 1,
1663 value: -1235,
1664 });
1665 assert_eq!(negative_decimal128.to_i128(), Some(-124));
1666 assert_eq!(negative_decimal128.to_i64(), Some(-124));
1667
1668 let small_negative_decimal64 = Number::Decimal64(Decimal64 {
1669 scale: 1,
1670 value: -4,
1671 });
1672 assert_eq!(small_negative_decimal64.to_i64(), Some(0));
1673
1674 let decimal256 = Number::Decimal256(Decimal256 {
1675 scale: 1,
1676 value: i256::from(1234),
1677 });
1678 assert_eq!(decimal256.to_i128(), Some(123));
1679 assert_eq!(decimal256.to_i64(), Some(123));
1680
1681 let float = Number::Float64(123.4);
1682 assert_eq!(float.to_i128(), Some(123));
1683 assert_eq!(float.to_i64(), Some(123));
1684
1685 let half_up = Number::Float64(123.5);
1686 assert_eq!(half_up.to_i128(), Some(124));
1687 assert_eq!(half_up.to_i64(), Some(124));
1688
1689 let negative_half_up = Number::Float64(-123.5);
1690 assert_eq!(negative_half_up.to_i128(), Some(-124));
1691 assert_eq!(negative_half_up.to_i64(), Some(-124));
1692
1693 let small_negative = Number::Float64(-0.4);
1694 assert_eq!(small_negative.to_i64(), Some(0));
1695
1696 let nan = Number::Float64(f64::NAN);
1697 assert_eq!(nan.to_i128(), None);
1698 assert_eq!(nan.to_i64(), None);
1699
1700 let inf = Number::Float64(f64::INFINITY);
1701 assert_eq!(inf.to_i128(), None);
1702 assert_eq!(inf.to_i64(), None);
1703
1704 let large = Number::Float64(1e100);
1705 assert_eq!(large.to_i128(), None);
1706 assert_eq!(large.to_i64(), None);
1707
1708 let i64_upper_bound = Number::Float64(-(i64::MIN as f64));
1709 assert_eq!(i64_upper_bound.to_i64(), None);
1710
1711 let overflowing_decimal128 = Number::Decimal128(Decimal128 {
1712 scale: 1,
1713 value: i128::from(i64::MAX) * 10 + 5,
1714 });
1715 assert_eq!(overflowing_decimal128.to_i64(), None);
1716 }
1717}