1use alloc::string::ToString;
2use core::cmp::Ordering;
3use core::fmt::{self, Write};
4use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
5use core::str::FromStr;
6use serde::{de, ser, Deserialize, Deserializer, Serialize};
7
8use crate::errors::{
9 CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, ErrorKind, OverflowError,
10 OverflowOperation, RoundUpOverflowError, StdError,
11};
12use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
13use crate::{Decimal256, SignedDecimal, SignedDecimal256, __internal::forward_ref_partial_eq};
14
15use super::Fraction;
16use super::Isqrt;
17use super::{Uint128, Uint256};
18
19#[derive(
23 Copy,
24 Clone,
25 Default,
26 PartialEq,
27 Eq,
28 PartialOrd,
29 Ord,
30 schemars::JsonSchema,
31 cw_schema::Schemaifier,
32)]
33#[schemaifier(type = cw_schema::NodeType::Decimal { precision: 128, signed: false })]
34pub struct Decimal(#[schemars(with = "String")] Uint128);
35
36forward_ref_partial_eq!(Decimal, Decimal);
37
38#[derive(Debug, PartialEq, Eq, thiserror::Error)]
39#[error("Decimal range exceeded")]
40pub struct DecimalRangeExceeded;
41
42impl Decimal {
43 const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
45 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); pub const DECIMAL_PLACES: u32 = 18; pub const MAX: Self = Self(Uint128::MAX);
52 pub const MIN: Self = Self(Uint128::MIN);
54
55 #[inline]
67 #[must_use]
68 pub const fn new(value: Uint128) -> Self {
69 Self(value)
70 }
71
72 #[deprecated(
75 since = "3.0.0",
76 note = "Use Decimal::new(Uint128::new(value)) instead"
77 )]
78 pub const fn raw(value: u128) -> Self {
79 Self(Uint128::new(value))
80 }
81
82 #[inline]
84 pub const fn one() -> Self {
85 Self(Self::DECIMAL_FRACTIONAL)
86 }
87
88 #[inline]
90 pub const fn zero() -> Self {
91 Self(Uint128::zero())
92 }
93
94 pub const fn percent(x: u64) -> Self {
106 let atomics = (x as u128) * 10_000_000_000_000_000;
108 Self(Uint128::new(atomics))
109 }
110
111 pub const fn permille(x: u64) -> Self {
123 let atomics = (x as u128) * 1_000_000_000_000_000;
125 Self(Uint128::new(atomics))
126 }
127
128 pub const fn bps(x: u64) -> Self {
142 let atomics = (x as u128) * 100_000_000_000_000;
144 Self(Uint128::new(atomics))
145 }
146
147 pub fn from_atomics(
169 atomics: impl Into<Uint128>,
170 decimal_places: u32,
171 ) -> Result<Self, DecimalRangeExceeded> {
172 let atomics = atomics.into();
173 const TEN: Uint128 = Uint128::new(10);
174 Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) {
175 Ordering::Less => {
176 let digits = (Self::DECIMAL_PLACES) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
179 atomics
180 .checked_mul(factor)
181 .map_err(|_| DecimalRangeExceeded)?,
182 )
183 }
184 Ordering::Equal => Self(atomics),
185 Ordering::Greater => {
186 let digits = decimal_places - (Self::DECIMAL_PLACES); if let Ok(factor) = TEN.checked_pow(digits) {
188 Self(atomics.checked_div(factor).unwrap()) } else {
190 Self(Uint128::zero())
194 }
195 }
196 })
197 }
198
199 pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
201 match Decimal::checked_from_ratio(numerator, denominator) {
202 Ok(value) => value,
203 Err(CheckedFromRatioError::DivideByZero) => {
204 panic!("Denominator must not be zero")
205 }
206 Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
207 }
208 }
209
210 pub fn checked_from_ratio(
212 numerator: impl Into<Uint128>,
213 denominator: impl Into<Uint128>,
214 ) -> Result<Self, CheckedFromRatioError> {
215 let numerator: Uint128 = numerator.into();
216 let denominator: Uint128 = denominator.into();
217 match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
218 Ok(ratio) => {
219 Ok(Decimal(ratio))
221 }
222 Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
223 Err(CheckedMultiplyRatioError::DivideByZero) => {
224 Err(CheckedFromRatioError::DivideByZero)
225 }
226 }
227 }
228
229 #[must_use]
230 pub const fn is_zero(&self) -> bool {
231 self.0.is_zero()
232 }
233
234 #[must_use]
253 #[inline]
254 pub const fn atomics(&self) -> Uint128 {
255 self.0
256 }
257
258 #[must_use]
263 #[inline]
264 pub const fn decimal_places(&self) -> u32 {
265 Self::DECIMAL_PLACES
266 }
267
268 #[must_use = "this returns the result of the operation, without modifying the original"]
270 pub fn floor(&self) -> Self {
271 Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
272 }
273
274 #[must_use = "this returns the result of the operation, without modifying the original"]
276 pub fn ceil(&self) -> Self {
277 match self.checked_ceil() {
278 Ok(value) => value,
279 Err(_) => panic!("attempt to ceil with overflow"),
280 }
281 }
282
283 pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
285 let floor = self.floor();
286 if floor == self {
287 Ok(floor)
288 } else {
289 floor
290 .checked_add(Decimal::one())
291 .map_err(|_| RoundUpOverflowError)
292 }
293 }
294
295 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
296 self.0
297 .checked_add(other.0)
298 .map(Self)
299 .map_err(|_| OverflowError::new(OverflowOperation::Add))
300 }
301
302 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
303 self.0
304 .checked_sub(other.0)
305 .map(Self)
306 .map_err(|_| OverflowError::new(OverflowOperation::Sub))
307 }
308
309 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
311 let result_as_uint256 = self.numerator().full_mul(other.numerator())
312 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); result_as_uint256
314 .try_into()
315 .map(Self)
316 .map_err(|_| OverflowError::new(OverflowOperation::Mul))
317 }
318
319 #[must_use = "this returns the result of the operation, without modifying the original"]
321 pub fn pow(self, exp: u32) -> Self {
322 match self.checked_pow(exp) {
323 Ok(value) => value,
324 Err(_) => panic!("Multiplication overflow"),
325 }
326 }
327
328 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
330 fn inner(mut x: Decimal, mut n: u32) -> Result<Decimal, OverflowError> {
334 if n == 0 {
335 return Ok(Decimal::one());
336 }
337
338 let mut y = Decimal::one();
339
340 while n > 1 {
341 if n % 2 == 0 {
342 x = x.checked_mul(x)?;
343 n /= 2;
344 } else {
345 y = x.checked_mul(y)?;
346 x = x.checked_mul(x)?;
347 n = (n - 1) / 2;
348 }
349 }
350
351 Ok(x * y)
352 }
353
354 inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
355 }
356
357 pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
358 Decimal::checked_from_ratio(self.numerator(), other.numerator())
359 }
360
361 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
362 self.0
363 .checked_rem(other.0)
364 .map(Self)
365 .map_err(|_| DivideByZeroError)
366 }
367
368 #[must_use = "this returns the result of the operation, without modifying the original"]
372 pub fn sqrt(&self) -> Self {
373 (0..=Self::DECIMAL_PLACES / 2)
381 .rev()
382 .find_map(|i| self.sqrt_with_precision(i))
383 .unwrap()
385 }
386
387 #[must_use = "this returns the result of the operation, without modifying the original"]
392 fn sqrt_with_precision(&self, precision: u32) -> Option<Self> {
393 let inner_mul = 100u128.pow(precision);
394 self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
395 let outer_mul = 10u128.pow(Self::DECIMAL_PLACES / 2 - precision);
396 Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
397 })
398 }
399
400 #[must_use = "this returns the result of the operation, without modifying the original"]
401 pub const fn abs_diff(self, other: Self) -> Self {
402 Self(self.0.abs_diff(other.0))
403 }
404
405 #[must_use = "this returns the result of the operation, without modifying the original"]
406 pub fn saturating_add(self, other: Self) -> Self {
407 match self.checked_add(other) {
408 Ok(value) => value,
409 Err(_) => Self::MAX,
410 }
411 }
412
413 #[must_use = "this returns the result of the operation, without modifying the original"]
414 pub fn saturating_sub(self, other: Self) -> Self {
415 match self.checked_sub(other) {
416 Ok(value) => value,
417 Err(_) => Self::zero(),
418 }
419 }
420
421 #[must_use = "this returns the result of the operation, without modifying the original"]
422 pub fn saturating_mul(self, other: Self) -> Self {
423 match self.checked_mul(other) {
424 Ok(value) => value,
425 Err(_) => Self::MAX,
426 }
427 }
428
429 #[must_use = "this returns the result of the operation, without modifying the original"]
430 pub fn saturating_pow(self, exp: u32) -> Self {
431 match self.checked_pow(exp) {
432 Ok(value) => value,
433 Err(_) => Self::MAX,
434 }
435 }
436
437 #[must_use = "this returns the result of the operation, without modifying the original"]
456 pub fn to_uint_floor(self) -> Uint128 {
457 self.0 / Self::DECIMAL_FRACTIONAL
458 }
459
460 #[must_use = "this returns the result of the operation, without modifying the original"]
479 pub fn to_uint_ceil(self) -> Uint128 {
480 let x = self.0;
483 let y = Self::DECIMAL_FRACTIONAL;
484 if x.is_zero() {
485 Uint128::zero()
486 } else {
487 Uint128::one() + ((x - Uint128::one()) / y)
488 }
489 }
490}
491
492impl Fraction<Uint128> for Decimal {
493 #[inline]
494 fn numerator(&self) -> Uint128 {
495 self.0
496 }
497
498 #[inline]
499 fn denominator(&self) -> Uint128 {
500 Self::DECIMAL_FRACTIONAL
501 }
502
503 fn inv(&self) -> Option<Self> {
507 if self.is_zero() {
508 None
509 } else {
510 Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
514 }
515 }
516}
517
518impl TryFrom<Decimal256> for Decimal {
519 type Error = DecimalRangeExceeded;
520
521 fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
522 value
523 .atomics()
524 .try_into()
525 .map(Decimal)
526 .map_err(|_| DecimalRangeExceeded)
527 }
528}
529
530impl TryFrom<SignedDecimal> for Decimal {
531 type Error = DecimalRangeExceeded;
532
533 fn try_from(value: SignedDecimal) -> Result<Self, Self::Error> {
534 value
535 .atomics()
536 .try_into()
537 .map(Decimal)
538 .map_err(|_| DecimalRangeExceeded)
539 }
540}
541
542impl TryFrom<SignedDecimal256> for Decimal {
543 type Error = DecimalRangeExceeded;
544
545 fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
546 value
547 .atomics()
548 .try_into()
549 .map(Decimal)
550 .map_err(|_| DecimalRangeExceeded)
551 }
552}
553
554impl TryFrom<Uint128> for Decimal {
555 type Error = DecimalRangeExceeded;
556
557 #[inline]
558 fn try_from(value: Uint128) -> Result<Self, Self::Error> {
559 Self::from_atomics(value, 0)
560 }
561}
562
563impl FromStr for Decimal {
564 type Err = StdError;
565
566 fn from_str(input: &str) -> Result<Self, Self::Err> {
573 let mut parts_iter = input.split('.');
574
575 let whole_part = parts_iter.next().unwrap(); let whole = whole_part.parse::<Uint128>()?;
577 let mut atomics = whole.checked_mul(Self::DECIMAL_FRACTIONAL)?;
578
579 if let Some(fractional_part) = parts_iter.next() {
580 let fractional = fractional_part.parse::<Uint128>()?;
581 let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
582 || {
583 StdError::msg(format_args!(
584 "Cannot parse more than {} fractional digits",
585 Self::DECIMAL_PLACES
586 ))
587 },
588 )?;
589 debug_assert!(exp <= Self::DECIMAL_PLACES);
590 let fractional_factor = Uint128::from(10u128.pow(exp));
591 atomics = atomics.checked_add(
592 fractional.checked_mul(fractional_factor).unwrap(),
595 )?;
596 }
597
598 if parts_iter.next().is_some() {
599 return Err(StdError::msg("Unexpected number of dots").with_kind(ErrorKind::Parsing));
600 }
601
602 Ok(Decimal(atomics))
603 }
604}
605
606impl fmt::Display for Decimal {
607 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
609 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
610
611 if fractional.is_zero() {
612 write!(f, "{whole}")
613 } else {
614 let fractional_string = format!(
615 "{:0>padding$}",
616 fractional,
617 padding = Self::DECIMAL_PLACES as usize
618 );
619 f.write_str(&whole.to_string())?;
620 f.write_char('.')?;
621 f.write_str(fractional_string.trim_end_matches('0'))?;
622 Ok(())
623 }
624 }
625}
626
627impl fmt::Debug for Decimal {
628 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629 write!(f, "Decimal({self})")
630 }
631}
632
633impl Add for Decimal {
634 type Output = Self;
635
636 fn add(self, other: Self) -> Self {
637 Decimal(self.0 + other.0)
638 }
639}
640forward_ref_binop!(impl Add, add for Decimal, Decimal);
641
642impl AddAssign for Decimal {
643 fn add_assign(&mut self, rhs: Decimal) {
644 *self = *self + rhs;
645 }
646}
647forward_ref_op_assign!(impl AddAssign, add_assign for Decimal, Decimal);
648
649impl Sub for Decimal {
650 type Output = Self;
651
652 fn sub(self, other: Self) -> Self {
653 Decimal(self.0 - other.0)
654 }
655}
656forward_ref_binop!(impl Sub, sub for Decimal, Decimal);
657
658impl SubAssign for Decimal {
659 fn sub_assign(&mut self, rhs: Decimal) {
660 *self = *self - rhs;
661 }
662}
663forward_ref_op_assign!(impl SubAssign, sub_assign for Decimal, Decimal);
664
665impl Mul for Decimal {
666 type Output = Self;
667
668 #[allow(clippy::suspicious_arithmetic_impl)]
669 fn mul(self, other: Self) -> Self {
670 let result_as_uint256 = self.numerator().full_mul(other.numerator())
676 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); match result_as_uint256.try_into() {
678 Ok(result) => Self(result),
679 Err(_) => panic!("attempt to multiply with overflow"),
680 }
681 }
682}
683forward_ref_binop!(impl Mul, mul for Decimal, Decimal);
684
685impl MulAssign for Decimal {
686 fn mul_assign(&mut self, rhs: Decimal) {
687 *self = *self * rhs;
688 }
689}
690forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal);
691
692impl Div for Decimal {
693 type Output = Self;
694
695 fn div(self, other: Self) -> Self {
696 match Decimal::checked_from_ratio(self.numerator(), other.numerator()) {
697 Ok(ratio) => ratio,
698 Err(CheckedFromRatioError::DivideByZero) => {
699 panic!("Division failed - denominator must not be zero")
700 }
701 Err(CheckedFromRatioError::Overflow) => {
702 panic!("Division failed - multiplication overflow")
703 }
704 }
705 }
706}
707forward_ref_binop!(impl Div, div for Decimal, Decimal);
708
709impl DivAssign for Decimal {
710 fn div_assign(&mut self, rhs: Decimal) {
711 *self = *self / rhs;
712 }
713}
714forward_ref_op_assign!(impl DivAssign, div_assign for Decimal, Decimal);
715
716impl Div<Uint128> for Decimal {
717 type Output = Self;
718
719 fn div(self, rhs: Uint128) -> Self::Output {
720 Decimal(self.0 / rhs)
721 }
722}
723
724impl DivAssign<Uint128> for Decimal {
725 fn div_assign(&mut self, rhs: Uint128) {
726 self.0 /= rhs;
727 }
728}
729
730impl Rem for Decimal {
731 type Output = Self;
732
733 #[inline]
737 fn rem(self, rhs: Self) -> Self {
738 Self(self.0.rem(rhs.0))
739 }
740}
741forward_ref_binop!(impl Rem, rem for Decimal, Decimal);
742
743impl RemAssign<Decimal> for Decimal {
744 fn rem_assign(&mut self, rhs: Decimal) {
745 *self = *self % rhs;
746 }
747}
748forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal);
749
750impl<A> core::iter::Sum<A> for Decimal
751where
752 Self: Add<A, Output = Self>,
753{
754 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
755 iter.fold(Self::zero(), Add::add)
756 }
757}
758
759impl Serialize for Decimal {
761 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
762 where
763 S: ser::Serializer,
764 {
765 serializer.serialize_str(&self.to_string())
766 }
767}
768
769impl<'de> Deserialize<'de> for Decimal {
771 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
772 where
773 D: Deserializer<'de>,
774 {
775 deserializer.deserialize_str(DecimalVisitor)
776 }
777}
778
779struct DecimalVisitor;
780
781impl de::Visitor<'_> for DecimalVisitor {
782 type Value = Decimal;
783
784 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
785 formatter.write_str("string-encoded decimal")
786 }
787
788 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
789 where
790 E: de::Error,
791 {
792 match Decimal::from_str(v) {
793 Ok(d) => Ok(d),
794 Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
795 }
796 }
797}
798
799#[cfg(test)]
800mod tests {
801 use super::*;
802
803 use alloc::vec::Vec;
804
805 fn dec(input: &str) -> Decimal {
806 Decimal::from_str(input).unwrap()
807 }
808
809 #[test]
810 fn decimal_new() {
811 let expected = Uint128::from(300u128);
812 assert_eq!(Decimal::new(expected).0, expected);
813 }
814
815 #[test]
816 #[allow(deprecated)]
817 fn decimal_raw() {
818 let value = 300u128;
819 assert_eq!(Decimal::raw(value).0.u128(), value);
820 }
821
822 #[test]
823 fn decimal_one() {
824 let value = Decimal::one();
825 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
826 }
827
828 #[test]
829 fn decimal_zero() {
830 let value = Decimal::zero();
831 assert!(value.0.is_zero());
832 }
833
834 #[test]
835 fn decimal_percent() {
836 let value = Decimal::percent(50);
837 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
838 }
839
840 #[test]
841 fn decimal_permille() {
842 let value = Decimal::permille(125);
843 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
844 }
845
846 #[test]
847 fn decimal_bps() {
848 let value = Decimal::bps(125);
849 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(80u8));
850 }
851
852 #[test]
853 fn decimal_from_decimal256_works() {
854 let too_big = Decimal256::new(Uint256::from(Uint128::MAX) + Uint256::one());
855 assert_eq!(Decimal::try_from(too_big), Err(DecimalRangeExceeded));
856
857 let just_right = Decimal256::new(Uint256::from(Uint128::MAX));
858 assert_eq!(Decimal::try_from(just_right), Ok(Decimal::MAX));
859
860 assert_eq!(Decimal::try_from(Decimal256::zero()), Ok(Decimal::zero()));
861 assert_eq!(Decimal::try_from(Decimal256::one()), Ok(Decimal::one()));
862 assert_eq!(
863 Decimal::try_from(Decimal256::percent(50)),
864 Ok(Decimal::percent(50))
865 );
866 }
867
868 #[test]
869 fn decimal_try_from_integer() {
870 let int = Uint128::new(0xDEADBEEF);
871 let decimal = Decimal::try_from(int).unwrap();
872 assert_eq!(int.to_string(), decimal.to_string());
873 }
874
875 #[test]
876 fn decimal_try_from_signed_works() {
877 assert_eq!(
878 Decimal::try_from(SignedDecimal::MAX).unwrap(),
879 Decimal::new(Uint128::new(SignedDecimal::MAX.atomics().i128() as u128))
880 );
881 assert_eq!(
882 Decimal::try_from(SignedDecimal::zero()).unwrap(),
883 Decimal::zero()
884 );
885 assert_eq!(
886 Decimal::try_from(SignedDecimal::one()).unwrap(),
887 Decimal::one()
888 );
889 assert_eq!(
890 Decimal::try_from(SignedDecimal::percent(50)).unwrap(),
891 Decimal::percent(50)
892 );
893 assert_eq!(
894 Decimal::try_from(SignedDecimal::negative_one()),
895 Err(DecimalRangeExceeded)
896 );
897 assert_eq!(
898 Decimal::try_from(SignedDecimal::MIN),
899 Err(DecimalRangeExceeded)
900 );
901 }
902
903 #[test]
904 fn decimal_from_atomics_works() {
905 let one = Decimal::one();
906 let two = one + one;
907
908 assert_eq!(Decimal::from_atomics(1u128, 0).unwrap(), one);
909 assert_eq!(Decimal::from_atomics(10u128, 1).unwrap(), one);
910 assert_eq!(Decimal::from_atomics(100u128, 2).unwrap(), one);
911 assert_eq!(Decimal::from_atomics(1000u128, 3).unwrap(), one);
912 assert_eq!(
913 Decimal::from_atomics(1000000000000000000u128, 18).unwrap(),
914 one
915 );
916 assert_eq!(
917 Decimal::from_atomics(10000000000000000000u128, 19).unwrap(),
918 one
919 );
920 assert_eq!(
921 Decimal::from_atomics(100000000000000000000u128, 20).unwrap(),
922 one
923 );
924
925 assert_eq!(Decimal::from_atomics(2u128, 0).unwrap(), two);
926 assert_eq!(Decimal::from_atomics(20u128, 1).unwrap(), two);
927 assert_eq!(Decimal::from_atomics(200u128, 2).unwrap(), two);
928 assert_eq!(Decimal::from_atomics(2000u128, 3).unwrap(), two);
929 assert_eq!(
930 Decimal::from_atomics(2000000000000000000u128, 18).unwrap(),
931 two
932 );
933 assert_eq!(
934 Decimal::from_atomics(20000000000000000000u128, 19).unwrap(),
935 two
936 );
937 assert_eq!(
938 Decimal::from_atomics(200000000000000000000u128, 20).unwrap(),
939 two
940 );
941
942 assert_eq!(
944 Decimal::from_atomics(4321u128, 20).unwrap(),
945 Decimal::from_str("0.000000000000000043").unwrap()
946 );
947 assert_eq!(
948 Decimal::from_atomics(6789u128, 20).unwrap(),
949 Decimal::from_str("0.000000000000000067").unwrap()
950 );
951 assert_eq!(
952 Decimal::from_atomics(u128::MAX, 38).unwrap(),
953 Decimal::from_str("3.402823669209384634").unwrap()
954 );
955 assert_eq!(
956 Decimal::from_atomics(u128::MAX, 39).unwrap(),
957 Decimal::from_str("0.340282366920938463").unwrap()
958 );
959 assert_eq!(
960 Decimal::from_atomics(u128::MAX, 45).unwrap(),
961 Decimal::from_str("0.000000340282366920").unwrap()
962 );
963 assert_eq!(
964 Decimal::from_atomics(u128::MAX, 51).unwrap(),
965 Decimal::from_str("0.000000000000340282").unwrap()
966 );
967 assert_eq!(
968 Decimal::from_atomics(u128::MAX, 56).unwrap(),
969 Decimal::from_str("0.000000000000000003").unwrap()
970 );
971 assert_eq!(
972 Decimal::from_atomics(u128::MAX, 57).unwrap(),
973 Decimal::from_str("0.000000000000000000").unwrap()
974 );
975 assert_eq!(
976 Decimal::from_atomics(u128::MAX, u32::MAX).unwrap(),
977 Decimal::from_str("0.000000000000000000").unwrap()
978 );
979
980 let max = Decimal::MAX;
982 assert_eq!(
983 Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
984 max
985 );
986
987 let result = Decimal::from_atomics(u128::MAX, 17);
989 assert_eq!(result.unwrap_err(), DecimalRangeExceeded);
990 }
991
992 #[test]
993 fn decimal_from_ratio_works() {
994 assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
996 assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
997 assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
998
999 assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
1001 assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
1002 assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
1003
1004 assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
1006 assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
1007
1008 assert_eq!(
1010 Decimal::from_ratio(1u64, 3u64),
1011 Decimal(Uint128::from(333_333_333_333_333_333u128))
1012 );
1013
1014 assert_eq!(
1016 Decimal::from_ratio(2u64, 3u64),
1017 Decimal(Uint128::from(666_666_666_666_666_666u128))
1018 );
1019
1020 assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
1022 assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
1023 assert_eq!(
1025 Decimal::from_ratio(340282366920938463463u128, 1u128),
1026 Decimal::from_str("340282366920938463463").unwrap()
1027 );
1028 }
1029
1030 #[test]
1031 #[should_panic(expected = "Denominator must not be zero")]
1032 fn decimal_from_ratio_panics_for_zero_denominator() {
1033 Decimal::from_ratio(1u128, 0u128);
1034 }
1035
1036 #[test]
1037 #[should_panic(expected = "Multiplication overflow")]
1038 fn decimal_from_ratio_panics_for_mul_overflow() {
1039 Decimal::from_ratio(u128::MAX, 1u128);
1040 }
1041
1042 #[test]
1043 fn decimal_checked_from_ratio_does_not_panic() {
1044 assert_eq!(
1045 Decimal::checked_from_ratio(1u128, 0u128),
1046 Err(CheckedFromRatioError::DivideByZero)
1047 );
1048
1049 assert_eq!(
1050 Decimal::checked_from_ratio(u128::MAX, 1u128),
1051 Err(CheckedFromRatioError::Overflow)
1052 );
1053 }
1054
1055 #[test]
1056 fn decimal_implements_fraction() {
1057 let fraction = Decimal::from_str("1234.567").unwrap();
1058 assert_eq!(
1059 fraction.numerator(),
1060 Uint128::from(1_234_567_000_000_000_000_000u128)
1061 );
1062 assert_eq!(
1063 fraction.denominator(),
1064 Uint128::from(1_000_000_000_000_000_000u128)
1065 );
1066 }
1067
1068 #[test]
1069 fn decimal_from_str_works() {
1070 assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
1072 assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
1073 assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
1074 assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
1075 assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
1076 assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
1077 assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
1078 assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
1079
1080 assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
1082 assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
1083 assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
1084 assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
1085
1086 assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
1087 assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
1088 assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
1089 assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
1090
1091 assert_eq!(
1093 Decimal::from_str("7.123456789012345678").unwrap(),
1094 Decimal(Uint128::from(7123456789012345678u128))
1095 );
1096 assert_eq!(
1097 Decimal::from_str("7.999999999999999999").unwrap(),
1098 Decimal(Uint128::from(7999999999999999999u128))
1099 );
1100
1101 assert_eq!(
1103 Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
1104 Decimal::MAX
1105 );
1106 }
1107
1108 #[test]
1109 fn decimal_from_str_errors_for_broken_whole_part() {
1110 assert!(Decimal::from_str("").is_err());
1111 assert!(Decimal::from_str(" ").is_err());
1112 assert!(Decimal::from_str("-1").is_err());
1113 }
1114
1115 #[test]
1116 fn decimal_from_str_errors_for_broken_fractional_part() {
1117 assert!(Decimal::from_str("1.").is_err());
1118 assert!(Decimal::from_str("1. ").is_err());
1119 assert!(Decimal::from_str("1.e").is_err());
1120 assert!(Decimal::from_str("1.2e3").is_err());
1121 }
1122
1123 #[test]
1124 fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
1125 assert!(Decimal::from_str("7.1234567890123456789")
1126 .unwrap_err()
1127 .to_string()
1128 .ends_with("Cannot parse more than 18 fractional digits"));
1129
1130 assert!(Decimal::from_str("7.1230000000000000000")
1132 .unwrap_err()
1133 .to_string()
1134 .ends_with("Cannot parse more than 18 fractional digits"));
1135 }
1136
1137 #[test]
1138 fn decimal_from_str_errors_for_invalid_number_of_dots() {
1139 assert!(Decimal::from_str("1.2.3").is_err());
1140 assert!(Decimal::from_str("1.2.3.4").is_err());
1141 }
1142
1143 #[test]
1144 fn decimal_from_str_errors_for_more_than_max_value() {
1145 assert!(Decimal::from_str("340282366920938463464").is_err());
1147
1148 assert!(Decimal::from_str("340282366920938463464.0").is_err());
1150 assert!(Decimal::from_str("340282366920938463463.374607431768211456").is_err());
1151 }
1152
1153 #[test]
1154 fn decimal_atomics_works() {
1155 let zero = Decimal::zero();
1156 let one = Decimal::one();
1157 let half = Decimal::percent(50);
1158 let two = Decimal::percent(200);
1159 let max = Decimal::MAX;
1160
1161 assert_eq!(zero.atomics(), Uint128::new(0));
1162 assert_eq!(one.atomics(), Uint128::new(1000000000000000000));
1163 assert_eq!(half.atomics(), Uint128::new(500000000000000000));
1164 assert_eq!(two.atomics(), Uint128::new(2000000000000000000));
1165 assert_eq!(max.atomics(), Uint128::MAX);
1166 }
1167
1168 #[test]
1169 fn decimal_decimal_places_works() {
1170 let zero = Decimal::zero();
1171 let one = Decimal::one();
1172 let half = Decimal::percent(50);
1173 let two = Decimal::percent(200);
1174 let max = Decimal::MAX;
1175
1176 assert_eq!(zero.decimal_places(), 18);
1177 assert_eq!(one.decimal_places(), 18);
1178 assert_eq!(half.decimal_places(), 18);
1179 assert_eq!(two.decimal_places(), 18);
1180 assert_eq!(max.decimal_places(), 18);
1181 }
1182
1183 #[test]
1184 fn decimal_is_zero_works() {
1185 assert!(Decimal::zero().is_zero());
1186 assert!(Decimal::percent(0).is_zero());
1187 assert!(Decimal::permille(0).is_zero());
1188
1189 assert!(!Decimal::one().is_zero());
1190 assert!(!Decimal::percent(123).is_zero());
1191 assert!(!Decimal::permille(1234).is_zero());
1192 }
1193
1194 #[test]
1195 fn decimal_inv_works() {
1196 assert_eq!(Decimal::zero().inv(), None);
1198
1199 assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
1201
1202 assert_eq!(
1204 Decimal::from_str("2").unwrap().inv(),
1205 Some(Decimal::from_str("0.5").unwrap())
1206 );
1207 assert_eq!(
1208 Decimal::from_str("20").unwrap().inv(),
1209 Some(Decimal::from_str("0.05").unwrap())
1210 );
1211 assert_eq!(
1212 Decimal::from_str("200").unwrap().inv(),
1213 Some(Decimal::from_str("0.005").unwrap())
1214 );
1215 assert_eq!(
1216 Decimal::from_str("2000").unwrap().inv(),
1217 Some(Decimal::from_str("0.0005").unwrap())
1218 );
1219
1220 assert_eq!(
1222 Decimal::from_str("3").unwrap().inv(),
1223 Some(Decimal::from_str("0.333333333333333333").unwrap())
1224 );
1225 assert_eq!(
1226 Decimal::from_str("6").unwrap().inv(),
1227 Some(Decimal::from_str("0.166666666666666666").unwrap())
1228 );
1229
1230 assert_eq!(
1232 Decimal::from_str("0.5").unwrap().inv(),
1233 Some(Decimal::from_str("2").unwrap())
1234 );
1235 assert_eq!(
1236 Decimal::from_str("0.05").unwrap().inv(),
1237 Some(Decimal::from_str("20").unwrap())
1238 );
1239 assert_eq!(
1240 Decimal::from_str("0.005").unwrap().inv(),
1241 Some(Decimal::from_str("200").unwrap())
1242 );
1243 assert_eq!(
1244 Decimal::from_str("0.0005").unwrap().inv(),
1245 Some(Decimal::from_str("2000").unwrap())
1246 );
1247 }
1248
1249 #[test]
1250 #[allow(clippy::op_ref)]
1251 fn decimal_add_works() {
1252 let value = Decimal::one() + Decimal::percent(50); assert_eq!(
1254 value.0,
1255 Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
1256 );
1257
1258 assert_eq!(
1259 Decimal::percent(5) + Decimal::percent(4),
1260 Decimal::percent(9)
1261 );
1262 assert_eq!(Decimal::percent(5) + Decimal::zero(), Decimal::percent(5));
1263 assert_eq!(Decimal::zero() + Decimal::zero(), Decimal::zero());
1264
1265 let a = Decimal::percent(15);
1267 let b = Decimal::percent(25);
1268 let expected = Decimal::percent(40);
1269 assert_eq!(a + b, expected);
1270 assert_eq!(&a + b, expected);
1271 assert_eq!(a + &b, expected);
1272 assert_eq!(&a + &b, expected);
1273 }
1274
1275 #[test]
1276 #[should_panic(expected = "attempt to add with overflow")]
1277 fn decimal_add_overflow_panics() {
1278 let _value = Decimal::MAX + Decimal::percent(50);
1279 }
1280
1281 #[test]
1282 fn decimal_add_assign_works() {
1283 let mut a = Decimal::percent(30);
1284 a += Decimal::percent(20);
1285 assert_eq!(a, Decimal::percent(50));
1286
1287 let mut a = Decimal::percent(15);
1289 let b = Decimal::percent(3);
1290 let expected = Decimal::percent(18);
1291 a += &b;
1292 assert_eq!(a, expected);
1293 }
1294
1295 #[test]
1296 #[allow(clippy::op_ref)]
1297 fn decimal_sub_works() {
1298 let value = Decimal::one() - Decimal::percent(50); assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
1300
1301 assert_eq!(
1302 Decimal::percent(9) - Decimal::percent(4),
1303 Decimal::percent(5)
1304 );
1305 assert_eq!(Decimal::percent(16) - Decimal::zero(), Decimal::percent(16));
1306 assert_eq!(Decimal::percent(16) - Decimal::percent(16), Decimal::zero());
1307 assert_eq!(Decimal::zero() - Decimal::zero(), Decimal::zero());
1308
1309 let a = Decimal::percent(13);
1311 let b = Decimal::percent(6);
1312 let expected = Decimal::percent(7);
1313 assert_eq!(a - b, expected);
1314 assert_eq!(&a - b, expected);
1315 assert_eq!(a - &b, expected);
1316 assert_eq!(&a - &b, expected);
1317 }
1318
1319 #[test]
1320 #[should_panic(expected = "attempt to subtract with overflow")]
1321 fn decimal_sub_overflow_panics() {
1322 let _value = Decimal::zero() - Decimal::percent(50);
1323 }
1324
1325 #[test]
1326 fn decimal_sub_assign_works() {
1327 let mut a = Decimal::percent(20);
1328 a -= Decimal::percent(2);
1329 assert_eq!(a, Decimal::percent(18));
1330
1331 let mut a = Decimal::percent(33);
1333 let b = Decimal::percent(13);
1334 let expected = Decimal::percent(20);
1335 a -= &b;
1336 assert_eq!(a, expected);
1337 }
1338
1339 #[test]
1340 #[allow(clippy::op_ref)]
1341 fn decimal_implements_mul() {
1342 let one = Decimal::one();
1343 let two = one + one;
1344 let half = Decimal::percent(50);
1345
1346 assert_eq!(one * Decimal::percent(0), Decimal::percent(0));
1348 assert_eq!(one * Decimal::percent(1), Decimal::percent(1));
1349 assert_eq!(one * Decimal::percent(10), Decimal::percent(10));
1350 assert_eq!(one * Decimal::percent(100), Decimal::percent(100));
1351 assert_eq!(one * Decimal::percent(1000), Decimal::percent(1000));
1352 assert_eq!(one * Decimal::MAX, Decimal::MAX);
1353 assert_eq!(Decimal::percent(0) * one, Decimal::percent(0));
1354 assert_eq!(Decimal::percent(1) * one, Decimal::percent(1));
1355 assert_eq!(Decimal::percent(10) * one, Decimal::percent(10));
1356 assert_eq!(Decimal::percent(100) * one, Decimal::percent(100));
1357 assert_eq!(Decimal::percent(1000) * one, Decimal::percent(1000));
1358 assert_eq!(Decimal::MAX * one, Decimal::MAX);
1359
1360 assert_eq!(two * Decimal::percent(0), Decimal::percent(0));
1362 assert_eq!(two * Decimal::percent(1), Decimal::percent(2));
1363 assert_eq!(two * Decimal::percent(10), Decimal::percent(20));
1364 assert_eq!(two * Decimal::percent(100), Decimal::percent(200));
1365 assert_eq!(two * Decimal::percent(1000), Decimal::percent(2000));
1366 assert_eq!(Decimal::percent(0) * two, Decimal::percent(0));
1367 assert_eq!(Decimal::percent(1) * two, Decimal::percent(2));
1368 assert_eq!(Decimal::percent(10) * two, Decimal::percent(20));
1369 assert_eq!(Decimal::percent(100) * two, Decimal::percent(200));
1370 assert_eq!(Decimal::percent(1000) * two, Decimal::percent(2000));
1371
1372 assert_eq!(half * Decimal::percent(0), Decimal::percent(0));
1374 assert_eq!(half * Decimal::percent(1), Decimal::permille(5));
1375 assert_eq!(half * Decimal::percent(10), Decimal::percent(5));
1376 assert_eq!(half * Decimal::percent(100), Decimal::percent(50));
1377 assert_eq!(half * Decimal::percent(1000), Decimal::percent(500));
1378 assert_eq!(Decimal::percent(0) * half, Decimal::percent(0));
1379 assert_eq!(Decimal::percent(1) * half, Decimal::permille(5));
1380 assert_eq!(Decimal::percent(10) * half, Decimal::percent(5));
1381 assert_eq!(Decimal::percent(100) * half, Decimal::percent(50));
1382 assert_eq!(Decimal::percent(1000) * half, Decimal::percent(500));
1383
1384 let a = dec("123.127726548762582");
1386 assert_eq!(a * dec("1"), dec("123.127726548762582"));
1387 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1388 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1389 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1390 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1391 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1392 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1393 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1394 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1395 assert_eq!(dec("1") * a, dec("123.127726548762582"));
1396 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1397 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1398 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1399 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1400 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1401 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1402 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1403 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1404
1405 let max = Decimal::MAX;
1407 assert_eq!(
1408 max * dec("1.0"),
1409 dec("340282366920938463463.374607431768211455")
1410 );
1411 assert_eq!(
1412 max * dec("0.1"),
1413 dec("34028236692093846346.337460743176821145")
1414 );
1415 assert_eq!(
1416 max * dec("0.01"),
1417 dec("3402823669209384634.633746074317682114")
1418 );
1419 assert_eq!(
1420 max * dec("0.001"),
1421 dec("340282366920938463.463374607431768211")
1422 );
1423 assert_eq!(
1424 max * dec("0.000001"),
1425 dec("340282366920938.463463374607431768")
1426 );
1427 assert_eq!(
1428 max * dec("0.000000001"),
1429 dec("340282366920.938463463374607431")
1430 );
1431 assert_eq!(
1432 max * dec("0.000000000001"),
1433 dec("340282366.920938463463374607")
1434 );
1435 assert_eq!(
1436 max * dec("0.000000000000001"),
1437 dec("340282.366920938463463374")
1438 );
1439 assert_eq!(
1440 max * dec("0.000000000000000001"),
1441 dec("340.282366920938463463")
1442 );
1443
1444 let a = Decimal::percent(20);
1446 let b = Decimal::percent(30);
1447 let expected = Decimal::percent(6);
1448 assert_eq!(a * b, expected);
1449 assert_eq!(&a * b, expected);
1450 assert_eq!(a * &b, expected);
1451 assert_eq!(&a * &b, expected);
1452 }
1453
1454 #[test]
1455 fn decimal_mul_assign_works() {
1456 let mut a = Decimal::percent(15);
1457 a *= Decimal::percent(60);
1458 assert_eq!(a, Decimal::percent(9));
1459
1460 let mut a = Decimal::percent(50);
1462 let b = Decimal::percent(20);
1463 a *= &b;
1464 assert_eq!(a, Decimal::percent(10));
1465 }
1466
1467 #[test]
1468 #[should_panic(expected = "attempt to multiply with overflow")]
1469 fn decimal_mul_overflow_panics() {
1470 let _value = Decimal::MAX * Decimal::percent(101);
1471 }
1472
1473 #[test]
1474 fn decimal_checked_mul() {
1475 let test_data = [
1476 (Decimal::zero(), Decimal::zero()),
1477 (Decimal::zero(), Decimal::one()),
1478 (Decimal::one(), Decimal::zero()),
1479 (Decimal::percent(10), Decimal::zero()),
1480 (Decimal::percent(10), Decimal::percent(5)),
1481 (Decimal::MAX, Decimal::one()),
1482 (Decimal::MAX / Uint128::new(2), Decimal::percent(200)),
1483 (Decimal::permille(6), Decimal::permille(13)),
1484 ];
1485
1486 for (x, y) in test_data.into_iter() {
1488 assert_eq!(x * y, x.checked_mul(y).unwrap());
1489 }
1490 }
1491
1492 #[test]
1493 fn decimal_checked_mul_overflow() {
1494 assert_eq!(
1495 Decimal::MAX.checked_mul(Decimal::percent(200)),
1496 Err(OverflowError::new(OverflowOperation::Mul))
1497 );
1498 }
1499
1500 #[test]
1501 #[allow(clippy::op_ref)]
1502 fn decimal_implements_div() {
1503 let one = Decimal::one();
1504 let two = one + one;
1505 let half = Decimal::percent(50);
1506
1507 assert_eq!(one / Decimal::percent(1), Decimal::percent(10_000));
1509 assert_eq!(one / Decimal::percent(10), Decimal::percent(1_000));
1510 assert_eq!(one / Decimal::percent(100), Decimal::percent(100));
1511 assert_eq!(one / Decimal::percent(1000), Decimal::percent(10));
1512 assert_eq!(Decimal::percent(0) / one, Decimal::percent(0));
1513 assert_eq!(Decimal::percent(1) / one, Decimal::percent(1));
1514 assert_eq!(Decimal::percent(10) / one, Decimal::percent(10));
1515 assert_eq!(Decimal::percent(100) / one, Decimal::percent(100));
1516 assert_eq!(Decimal::percent(1000) / one, Decimal::percent(1000));
1517
1518 assert_eq!(two / Decimal::percent(1), Decimal::percent(20_000));
1520 assert_eq!(two / Decimal::percent(10), Decimal::percent(2_000));
1521 assert_eq!(two / Decimal::percent(100), Decimal::percent(200));
1522 assert_eq!(two / Decimal::percent(1000), Decimal::percent(20));
1523 assert_eq!(Decimal::percent(0) / two, Decimal::percent(0));
1524 assert_eq!(Decimal::percent(1) / two, dec("0.005"));
1525 assert_eq!(Decimal::percent(10) / two, Decimal::percent(5));
1526 assert_eq!(Decimal::percent(100) / two, Decimal::percent(50));
1527 assert_eq!(Decimal::percent(1000) / two, Decimal::percent(500));
1528
1529 assert_eq!(half / Decimal::percent(1), Decimal::percent(5_000));
1531 assert_eq!(half / Decimal::percent(10), Decimal::percent(500));
1532 assert_eq!(half / Decimal::percent(100), Decimal::percent(50));
1533 assert_eq!(half / Decimal::percent(1000), Decimal::percent(5));
1534 assert_eq!(Decimal::percent(0) / half, Decimal::percent(0));
1535 assert_eq!(Decimal::percent(1) / half, Decimal::percent(2));
1536 assert_eq!(Decimal::percent(10) / half, Decimal::percent(20));
1537 assert_eq!(Decimal::percent(100) / half, Decimal::percent(200));
1538 assert_eq!(Decimal::percent(1000) / half, Decimal::percent(2000));
1539
1540 let a = dec("123127726548762582");
1542 assert_eq!(a / dec("1"), dec("123127726548762582"));
1543 assert_eq!(a / dec("10"), dec("12312772654876258.2"));
1544 assert_eq!(a / dec("100"), dec("1231277265487625.82"));
1545 assert_eq!(a / dec("1000"), dec("123127726548762.582"));
1546 assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
1547 assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
1548 assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
1549 assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
1550 assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
1551 assert_eq!(dec("1") / a, dec("0.000000000000000008"));
1552 assert_eq!(dec("10") / a, dec("0.000000000000000081"));
1553 assert_eq!(dec("100") / a, dec("0.000000000000000812"));
1554 assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
1555 assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
1556 assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
1557 assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
1558 assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
1559 assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
1560
1561 let a = dec("0.123127726548762582");
1563 assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
1564 assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
1565 assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
1566 assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
1567 assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
1568 assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
1569 assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
1570 assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
1571 assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
1572
1573 assert_eq!(
1574 Decimal::percent(15) / Decimal::percent(60),
1575 Decimal::percent(25)
1576 );
1577
1578 let a = Decimal::percent(100);
1580 let b = Decimal::percent(20);
1581 let expected = Decimal::percent(500);
1582 assert_eq!(a / b, expected);
1583 assert_eq!(&a / b, expected);
1584 assert_eq!(a / &b, expected);
1585 assert_eq!(&a / &b, expected);
1586 }
1587
1588 #[test]
1589 fn decimal_div_assign_works() {
1590 let mut a = Decimal::percent(15);
1591 a /= Decimal::percent(20);
1592 assert_eq!(a, Decimal::percent(75));
1593
1594 let mut a = Decimal::percent(50);
1596 let b = Decimal::percent(20);
1597 a /= &b;
1598 assert_eq!(a, Decimal::percent(250));
1599 }
1600
1601 #[test]
1602 #[should_panic(expected = "Division failed - multiplication overflow")]
1603 fn decimal_div_overflow_panics() {
1604 let _value = Decimal::MAX / Decimal::percent(10);
1605 }
1606
1607 #[test]
1608 #[should_panic(expected = "Division failed - denominator must not be zero")]
1609 fn decimal_div_by_zero_panics() {
1610 let _value = Decimal::one() / Decimal::zero();
1611 }
1612
1613 #[test]
1614 fn decimal_uint128_division() {
1615 let left = Decimal::percent(150); let right = Uint128::new(3);
1618 assert_eq!(left / right, Decimal::percent(50));
1619
1620 let left = Decimal::zero();
1622 let right = Uint128::new(300);
1623 assert_eq!(left / right, Decimal::zero());
1624 }
1625
1626 #[test]
1627 #[should_panic(expected = "attempt to divide by zero")]
1628 fn decimal_uint128_divide_by_zero() {
1629 let left = Decimal::percent(150); let right = Uint128::new(0);
1631 let _result = left / right;
1632 }
1633
1634 #[test]
1635 fn decimal_uint128_div_assign() {
1636 let mut dec = Decimal::percent(150); dec /= Uint128::new(3);
1639 assert_eq!(dec, Decimal::percent(50));
1640
1641 let mut dec = Decimal::zero();
1643 dec /= Uint128::new(300);
1644 assert_eq!(dec, Decimal::zero());
1645 }
1646
1647 #[test]
1648 #[should_panic(expected = "attempt to divide by zero")]
1649 fn decimal_uint128_div_assign_by_zero() {
1650 let mut dec = Decimal::percent(50);
1652 dec /= Uint128::new(0);
1653 }
1654
1655 #[test]
1656 fn decimal_uint128_sqrt() {
1657 assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1658
1659 assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1660 assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1661 }
1662
1663 #[test]
1665 fn decimal_uint128_sqrt_is_precise() {
1666 assert_eq!(
1667 Decimal::from_str("2").unwrap().sqrt(),
1668 Decimal::from_str("1.414213562373095048").unwrap() );
1670 }
1671
1672 #[test]
1673 fn decimal_uint128_sqrt_does_not_overflow() {
1674 assert_eq!(
1675 Decimal::from_str("400").unwrap().sqrt(),
1676 Decimal::from_str("20").unwrap()
1677 );
1678 }
1679
1680 #[test]
1681 fn decimal_uint128_sqrt_intermediate_precision_used() {
1682 assert_eq!(
1683 Decimal::from_str("400001").unwrap().sqrt(),
1684 Decimal::from_str("632.456322602596803200").unwrap()
1688 );
1689 }
1690
1691 #[test]
1692 fn decimal_checked_pow() {
1693 for exp in 0..10 {
1694 assert_eq!(Decimal::one().checked_pow(exp).unwrap(), Decimal::one());
1695 }
1696
1697 assert_eq!(Decimal::zero().checked_pow(0).unwrap(), Decimal::one());
1700
1701 for exp in 1..10 {
1702 assert_eq!(Decimal::zero().checked_pow(exp).unwrap(), Decimal::zero());
1703 }
1704
1705 for num in &[
1706 Decimal::percent(50),
1707 Decimal::percent(99),
1708 Decimal::percent(200),
1709 ] {
1710 assert_eq!(num.checked_pow(0).unwrap(), Decimal::one())
1711 }
1712
1713 assert_eq!(
1714 Decimal::percent(20).checked_pow(2).unwrap(),
1715 Decimal::percent(4)
1716 );
1717
1718 assert_eq!(
1719 Decimal::percent(20).checked_pow(3).unwrap(),
1720 Decimal::permille(8)
1721 );
1722
1723 assert_eq!(
1724 Decimal::percent(200).checked_pow(4).unwrap(),
1725 Decimal::percent(1600)
1726 );
1727
1728 assert_eq!(
1729 Decimal::percent(200).checked_pow(4).unwrap(),
1730 Decimal::percent(1600)
1731 );
1732
1733 assert_eq!(
1734 Decimal::percent(700).checked_pow(5).unwrap(),
1735 Decimal::percent(1680700)
1736 );
1737
1738 assert_eq!(
1739 Decimal::percent(700).checked_pow(8).unwrap(),
1740 Decimal::percent(576480100)
1741 );
1742
1743 assert_eq!(
1744 Decimal::percent(700).checked_pow(10).unwrap(),
1745 Decimal::percent(28247524900)
1746 );
1747
1748 assert_eq!(
1749 Decimal::percent(120).checked_pow(123).unwrap(),
1750 Decimal(5486473221892422150877397607u128.into())
1751 );
1752
1753 assert_eq!(
1754 Decimal::percent(10).checked_pow(2).unwrap(),
1755 Decimal(10000000000000000u128.into())
1756 );
1757
1758 assert_eq!(
1759 Decimal::percent(10).checked_pow(18).unwrap(),
1760 Decimal(1u128.into())
1761 );
1762 }
1763
1764 #[test]
1765 fn decimal_checked_pow_overflow() {
1766 assert_eq!(
1767 Decimal::MAX.checked_pow(2),
1768 Err(OverflowError::new(OverflowOperation::Pow))
1769 );
1770 }
1771
1772 #[test]
1773 fn decimal_to_string() {
1774 assert_eq!(Decimal::zero().to_string(), "0");
1776 assert_eq!(Decimal::one().to_string(), "1");
1777 assert_eq!(Decimal::percent(500).to_string(), "5");
1778
1779 assert_eq!(Decimal::percent(125).to_string(), "1.25");
1781 assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1782 assert_eq!(Decimal::percent(3).to_string(), "0.03");
1783 assert_eq!(Decimal::permille(987).to_string(), "0.987");
1784
1785 assert_eq!(
1786 Decimal(Uint128::from(1u128)).to_string(),
1787 "0.000000000000000001"
1788 );
1789 assert_eq!(
1790 Decimal(Uint128::from(10u128)).to_string(),
1791 "0.00000000000000001"
1792 );
1793 assert_eq!(
1794 Decimal(Uint128::from(100u128)).to_string(),
1795 "0.0000000000000001"
1796 );
1797 assert_eq!(
1798 Decimal(Uint128::from(1000u128)).to_string(),
1799 "0.000000000000001"
1800 );
1801 assert_eq!(
1802 Decimal(Uint128::from(10000u128)).to_string(),
1803 "0.00000000000001"
1804 );
1805 assert_eq!(
1806 Decimal(Uint128::from(100000u128)).to_string(),
1807 "0.0000000000001"
1808 );
1809 assert_eq!(
1810 Decimal(Uint128::from(1000000u128)).to_string(),
1811 "0.000000000001"
1812 );
1813 assert_eq!(
1814 Decimal(Uint128::from(10000000u128)).to_string(),
1815 "0.00000000001"
1816 );
1817 assert_eq!(
1818 Decimal(Uint128::from(100000000u128)).to_string(),
1819 "0.0000000001"
1820 );
1821 assert_eq!(
1822 Decimal(Uint128::from(1000000000u128)).to_string(),
1823 "0.000000001"
1824 );
1825 assert_eq!(
1826 Decimal(Uint128::from(10000000000u128)).to_string(),
1827 "0.00000001"
1828 );
1829 assert_eq!(
1830 Decimal(Uint128::from(100000000000u128)).to_string(),
1831 "0.0000001"
1832 );
1833 assert_eq!(
1834 Decimal(Uint128::from(10000000000000u128)).to_string(),
1835 "0.00001"
1836 );
1837 assert_eq!(
1838 Decimal(Uint128::from(100000000000000u128)).to_string(),
1839 "0.0001"
1840 );
1841 assert_eq!(
1842 Decimal(Uint128::from(1000000000000000u128)).to_string(),
1843 "0.001"
1844 );
1845 assert_eq!(
1846 Decimal(Uint128::from(10000000000000000u128)).to_string(),
1847 "0.01"
1848 );
1849 assert_eq!(
1850 Decimal(Uint128::from(100000000000000000u128)).to_string(),
1851 "0.1"
1852 );
1853 }
1854
1855 #[test]
1856 fn decimal_iter_sum() {
1857 let items = vec![
1858 Decimal::zero(),
1859 Decimal(Uint128::from(2u128)),
1860 Decimal(Uint128::from(2u128)),
1861 ];
1862 assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1863 assert_eq!(
1864 items.into_iter().sum::<Decimal>(),
1865 Decimal(Uint128::from(4u128))
1866 );
1867
1868 let empty: Vec<Decimal> = vec![];
1869 assert_eq!(Decimal::zero(), empty.iter().sum::<Decimal>());
1870 }
1871
1872 #[test]
1873 fn decimal_serialize() {
1874 assert_eq!(serde_json::to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1875 assert_eq!(serde_json::to_vec(&Decimal::one()).unwrap(), br#""1""#);
1876 assert_eq!(
1877 serde_json::to_vec(&Decimal::percent(8)).unwrap(),
1878 br#""0.08""#
1879 );
1880 assert_eq!(
1881 serde_json::to_vec(&Decimal::percent(87)).unwrap(),
1882 br#""0.87""#
1883 );
1884 assert_eq!(
1885 serde_json::to_vec(&Decimal::percent(876)).unwrap(),
1886 br#""8.76""#
1887 );
1888 assert_eq!(
1889 serde_json::to_vec(&Decimal::percent(8765)).unwrap(),
1890 br#""87.65""#
1891 );
1892 }
1893
1894 #[test]
1895 fn decimal_deserialize() {
1896 assert_eq!(
1897 serde_json::from_slice::<Decimal>(br#""0""#).unwrap(),
1898 Decimal::zero()
1899 );
1900 assert_eq!(
1901 serde_json::from_slice::<Decimal>(br#""1""#).unwrap(),
1902 Decimal::one()
1903 );
1904 assert_eq!(
1905 serde_json::from_slice::<Decimal>(br#""000""#).unwrap(),
1906 Decimal::zero()
1907 );
1908 assert_eq!(
1909 serde_json::from_slice::<Decimal>(br#""001""#).unwrap(),
1910 Decimal::one()
1911 );
1912
1913 assert_eq!(
1914 serde_json::from_slice::<Decimal>(br#""0.08""#).unwrap(),
1915 Decimal::percent(8)
1916 );
1917 assert_eq!(
1918 serde_json::from_slice::<Decimal>(br#""0.87""#).unwrap(),
1919 Decimal::percent(87)
1920 );
1921 assert_eq!(
1922 serde_json::from_slice::<Decimal>(br#""8.76""#).unwrap(),
1923 Decimal::percent(876)
1924 );
1925 assert_eq!(
1926 serde_json::from_slice::<Decimal>(br#""87.65""#).unwrap(),
1927 Decimal::percent(8765)
1928 );
1929 }
1930
1931 #[test]
1932 fn decimal_abs_diff_works() {
1933 let a = Decimal::percent(285);
1934 let b = Decimal::percent(200);
1935 let expected = Decimal::percent(85);
1936 assert_eq!(a.abs_diff(b), expected);
1937 assert_eq!(b.abs_diff(a), expected);
1938 }
1939
1940 #[test]
1941 #[allow(clippy::op_ref)]
1942 fn decimal_rem_works() {
1943 assert_eq!(
1945 Decimal::percent(402) % Decimal::percent(111),
1946 Decimal::percent(69)
1947 );
1948
1949 assert_eq!(
1951 Decimal::percent(1525) % Decimal::percent(400),
1952 Decimal::percent(325)
1953 );
1954
1955 let a = Decimal::percent(318);
1956 let b = Decimal::percent(317);
1957 let expected = Decimal::percent(1);
1958 assert_eq!(a % b, expected);
1959 assert_eq!(a % &b, expected);
1960 assert_eq!(&a % b, expected);
1961 assert_eq!(&a % &b, expected);
1962 }
1963
1964 #[test]
1965 fn decimal_rem_assign_works() {
1966 let mut a = Decimal::percent(17673);
1967 a %= Decimal::percent(2362);
1968 assert_eq!(a, Decimal::percent(1139)); let mut a = Decimal::percent(4262);
1971 let b = Decimal::percent(1270);
1972 a %= &b;
1973 assert_eq!(a, Decimal::percent(452)); }
1975
1976 #[test]
1977 #[should_panic(expected = "divisor of zero")]
1978 fn decimal_rem_panics_for_zero() {
1979 let _ = Decimal::percent(777) % Decimal::zero();
1980 }
1981
1982 #[test]
1983 fn decimal_checked_methods() {
1984 assert_eq!(
1986 Decimal::percent(402)
1987 .checked_add(Decimal::percent(111))
1988 .unwrap(),
1989 Decimal::percent(513)
1990 );
1991 assert!(matches!(
1992 Decimal::MAX.checked_add(Decimal::percent(1)),
1993 Err(OverflowError { .. })
1994 ));
1995
1996 assert_eq!(
1998 Decimal::percent(1111)
1999 .checked_sub(Decimal::percent(111))
2000 .unwrap(),
2001 Decimal::percent(1000)
2002 );
2003 assert!(matches!(
2004 Decimal::zero().checked_sub(Decimal::percent(1)),
2005 Err(OverflowError { .. })
2006 ));
2007
2008 assert_eq!(
2010 Decimal::percent(30)
2011 .checked_div(Decimal::percent(200))
2012 .unwrap(),
2013 Decimal::percent(15)
2014 );
2015 assert_eq!(
2016 Decimal::percent(88)
2017 .checked_div(Decimal::percent(20))
2018 .unwrap(),
2019 Decimal::percent(440)
2020 );
2021 assert!(matches!(
2022 Decimal::MAX.checked_div(Decimal::zero()),
2023 Err(CheckedFromRatioError::DivideByZero)
2024 ));
2025 assert!(matches!(
2026 Decimal::MAX.checked_div(Decimal::percent(1)),
2027 Err(CheckedFromRatioError::Overflow)
2028 ));
2029
2030 assert_eq!(
2032 Decimal::percent(402)
2033 .checked_rem(Decimal::percent(111))
2034 .unwrap(),
2035 Decimal::percent(69)
2036 );
2037 assert_eq!(
2038 Decimal::percent(1525)
2039 .checked_rem(Decimal::percent(400))
2040 .unwrap(),
2041 Decimal::percent(325)
2042 );
2043 assert!(matches!(
2044 Decimal::MAX.checked_rem(Decimal::zero()),
2045 Err(DivideByZeroError { .. })
2046 ));
2047 }
2048
2049 #[test]
2050 fn decimal_pow_works() {
2051 assert_eq!(Decimal::percent(200).pow(2), Decimal::percent(400));
2052 assert_eq!(Decimal::percent(200).pow(10), Decimal::percent(102400));
2053 }
2054
2055 #[test]
2056 #[should_panic]
2057 fn decimal_pow_overflow_panics() {
2058 _ = Decimal::MAX.pow(2u32);
2059 }
2060
2061 #[test]
2062 fn decimal_saturating_works() {
2063 assert_eq!(
2064 Decimal::percent(200).saturating_add(Decimal::percent(200)),
2065 Decimal::percent(400)
2066 );
2067 assert_eq!(
2068 Decimal::MAX.saturating_add(Decimal::percent(200)),
2069 Decimal::MAX
2070 );
2071 assert_eq!(
2072 Decimal::percent(200).saturating_sub(Decimal::percent(100)),
2073 Decimal::percent(100)
2074 );
2075 assert_eq!(
2076 Decimal::zero().saturating_sub(Decimal::percent(200)),
2077 Decimal::zero()
2078 );
2079 assert_eq!(
2080 Decimal::percent(200).saturating_mul(Decimal::percent(50)),
2081 Decimal::percent(100)
2082 );
2083 assert_eq!(
2084 Decimal::MAX.saturating_mul(Decimal::percent(200)),
2085 Decimal::MAX
2086 );
2087 assert_eq!(
2088 Decimal::percent(400).saturating_pow(2u32),
2089 Decimal::percent(1600)
2090 );
2091 assert_eq!(Decimal::MAX.saturating_pow(2u32), Decimal::MAX);
2092 }
2093
2094 #[test]
2095 fn decimal_rounding() {
2096 assert_eq!(Decimal::one().floor(), Decimal::one());
2097 assert_eq!(Decimal::percent(150).floor(), Decimal::one());
2098 assert_eq!(Decimal::percent(199).floor(), Decimal::one());
2099 assert_eq!(Decimal::percent(200).floor(), Decimal::percent(200));
2100 assert_eq!(Decimal::percent(99).floor(), Decimal::zero());
2101
2102 assert_eq!(Decimal::one().ceil(), Decimal::one());
2103 assert_eq!(Decimal::percent(150).ceil(), Decimal::percent(200));
2104 assert_eq!(Decimal::percent(199).ceil(), Decimal::percent(200));
2105 assert_eq!(Decimal::percent(99).ceil(), Decimal::one());
2106 assert_eq!(Decimal(Uint128::from(1u128)).ceil(), Decimal::one());
2107 }
2108
2109 #[test]
2110 #[should_panic(expected = "attempt to ceil with overflow")]
2111 fn decimal_ceil_panics() {
2112 let _ = Decimal::MAX.ceil();
2113 }
2114
2115 #[test]
2116 fn decimal_checked_ceil() {
2117 assert_eq!(
2118 Decimal::percent(199).checked_ceil(),
2119 Ok(Decimal::percent(200))
2120 );
2121 assert!(matches!(
2122 Decimal::MAX.checked_ceil(),
2123 Err(RoundUpOverflowError { .. })
2124 ));
2125 }
2126
2127 #[test]
2128 fn decimal_to_uint_floor_works() {
2129 let d = Decimal::from_str("12.000000000000000001").unwrap();
2130 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2131 let d = Decimal::from_str("12.345").unwrap();
2132 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2133 let d = Decimal::from_str("12.999").unwrap();
2134 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2135 let d = Decimal::from_str("0.98451384").unwrap();
2136 assert_eq!(d.to_uint_floor(), Uint128::new(0));
2137
2138 let d = Decimal::from_str("75.0").unwrap();
2139 assert_eq!(d.to_uint_floor(), Uint128::new(75));
2140 let d = Decimal::from_str("0.0").unwrap();
2141 assert_eq!(d.to_uint_floor(), Uint128::new(0));
2142
2143 let d = Decimal::MAX;
2144 assert_eq!(d.to_uint_floor(), Uint128::new(340282366920938463463));
2145
2146 let tests = vec![
2149 (Decimal::from_str("12.345").unwrap(), 12u128),
2150 (Decimal::from_str("0.98451384").unwrap(), 0u128),
2151 (Decimal::from_str("178.0").unwrap(), 178u128),
2152 (Decimal::MIN, 0u128),
2153 (Decimal::MAX, u128::MAX / Decimal::DECIMAL_FRACTIONAL.u128()),
2154 ];
2155 for (my_decimal, expected) in tests.into_iter() {
2156 assert_eq!(my_decimal.to_uint_floor(), Uint128::new(expected));
2157 }
2158 }
2159
2160 #[test]
2161 fn decimal_to_uint_ceil_works() {
2162 let d = Decimal::from_str("12.000000000000000001").unwrap();
2163 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2164 let d = Decimal::from_str("12.345").unwrap();
2165 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2166 let d = Decimal::from_str("12.999").unwrap();
2167 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2168
2169 let d = Decimal::from_str("75.0").unwrap();
2170 assert_eq!(d.to_uint_ceil(), Uint128::new(75));
2171 let d = Decimal::from_str("0.0").unwrap();
2172 assert_eq!(d.to_uint_ceil(), Uint128::new(0));
2173
2174 let d = Decimal::MAX;
2175 assert_eq!(d.to_uint_ceil(), Uint128::new(340282366920938463464));
2176 }
2177
2178 #[test]
2179 fn decimal_partial_eq() {
2180 let test_cases = [
2181 ("1", "1", true),
2182 ("0.5", "0.5", true),
2183 ("0.5", "0.51", false),
2184 ("0", "0.00000", true),
2185 ]
2186 .into_iter()
2187 .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
2188
2189 #[allow(clippy::op_ref)]
2190 for (lhs, rhs, expected) in test_cases {
2191 assert_eq!(lhs == rhs, expected);
2192 assert_eq!(&lhs == rhs, expected);
2193 assert_eq!(lhs == &rhs, expected);
2194 assert_eq!(&lhs == &rhs, expected);
2195 }
2196 }
2197
2198 #[test]
2199 fn decimal_implements_debug() {
2200 let decimal = Decimal::from_str("123.45").unwrap();
2201 assert_eq!(format!("{decimal:?}"), "Decimal(123.45)");
2202
2203 let test_cases = ["5", "5.01", "42", "0", "2"];
2204 for s in test_cases {
2205 let decimal = Decimal::from_str(s).unwrap();
2206 let expected = format!("Decimal({s})");
2207 assert_eq!(format!("{decimal:?}"), expected);
2208 }
2209 }
2210}