1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5 ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8
9use crate::errors::{
10 CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
11 OverflowOperation, StdError,
12};
13use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
14use crate::{
15 __internal::forward_ref_partial_eq, impl_mul_fraction, Fraction, Int128, Int256, Int512, Int64,
16 Uint256, Uint64,
17};
18
19use super::conversion::{
20 forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, wrapped_int_to_primitive,
21};
22use super::impl_int_serde;
23use super::num_consts::NumConsts;
24
25#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
45pub struct Uint128(#[schemars(with = "String")] pub(crate) u128);
46
47impl_int_serde!(Uint128);
48forward_ref_partial_eq!(Uint128, Uint128);
49
50impl Uint128 {
51 pub const MAX: Self = Self(u128::MAX);
52 pub const MIN: Self = Self(u128::MIN);
53
54 #[inline]
58 #[must_use]
59 pub const fn new(value: u128) -> Self {
60 Uint128(value)
61 }
62
63 #[inline]
65 pub const fn zero() -> Self {
66 Uint128(0)
67 }
68
69 #[inline]
71 pub const fn one() -> Self {
72 Self(1)
73 }
74
75 pub const fn u128(&self) -> u128 {
77 self.0
78 }
79
80 from_and_to_bytes!(u128, 16);
81
82 #[must_use]
83 pub const fn is_zero(&self) -> bool {
84 self.0 == 0
85 }
86
87 #[must_use = "this returns the result of the operation, without modifying the original"]
88 pub const fn pow(self, exp: u32) -> Self {
89 match self.0.checked_pow(exp) {
90 Some(val) => Self(val),
91 None => panic!("attempt to exponentiate with overflow"),
92 }
93 }
94
95 #[must_use = "this returns the result of the operation, without modifying the original"]
101 pub fn ilog2(self) -> u32 {
102 self.0.checked_ilog2().unwrap()
103 }
104
105 #[must_use = "this returns the result of the operation, without modifying the original"]
110 pub fn multiply_ratio<A: Into<u128>, B: Into<u128>>(
111 &self,
112 numerator: A,
113 denominator: B,
114 ) -> Uint128 {
115 match self.checked_multiply_ratio(numerator, denominator) {
116 Ok(value) => value,
117 Err(CheckedMultiplyRatioError::DivideByZero) => {
118 panic!("Denominator must not be zero")
119 }
120 Err(CheckedMultiplyRatioError::Overflow) => panic!("Multiplication overflow"),
121 }
122 }
123
124 pub fn checked_multiply_ratio<A: Into<u128>, B: Into<u128>>(
129 &self,
130 numerator: A,
131 denominator: B,
132 ) -> Result<Uint128, CheckedMultiplyRatioError> {
133 let numerator: u128 = numerator.into();
134 let denominator: u128 = denominator.into();
135 if denominator == 0 {
136 return Err(CheckedMultiplyRatioError::DivideByZero);
137 }
138 match (self.full_mul(numerator) / Uint256::from(denominator)).try_into() {
139 Ok(ratio) => Ok(ratio),
140 Err(_) => Err(CheckedMultiplyRatioError::Overflow),
141 }
142 }
143
144 #[must_use = "this returns the result of the operation, without modifying the original"]
157 pub fn full_mul(self, rhs: impl Into<Self>) -> Uint256 {
158 Uint256::from(self)
159 .checked_mul(Uint256::from(rhs.into()))
160 .unwrap()
161 }
162
163 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
164 self.0
165 .checked_add(other.0)
166 .map(Self)
167 .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
168 }
169
170 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
171 self.0
172 .checked_sub(other.0)
173 .map(Self)
174 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
175 }
176
177 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
178 self.0
179 .checked_mul(other.0)
180 .map(Self)
181 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
182 }
183
184 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
185 self.0
186 .checked_pow(exp)
187 .map(Self)
188 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
189 }
190
191 pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
192 self.0
193 .checked_div(other.0)
194 .map(Self)
195 .ok_or(DivideByZeroError)
196 }
197
198 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
199 self.0
200 .checked_div_euclid(other.0)
201 .map(Self)
202 .ok_or(DivideByZeroError)
203 }
204
205 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
206 self.0
207 .checked_rem(other.0)
208 .map(Self)
209 .ok_or(DivideByZeroError)
210 }
211
212 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
213 if other >= 128 {
214 return Err(OverflowError::new(OverflowOperation::Shr));
215 }
216
217 Ok(Self(self.0.shr(other)))
218 }
219
220 pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
221 if other >= 128 {
222 return Err(OverflowError::new(OverflowOperation::Shl));
223 }
224
225 Ok(Self(self.0.shl(other)))
226 }
227
228 #[must_use = "this returns the result of the operation, without modifying the original"]
229 #[inline]
230 pub fn wrapping_add(self, other: Self) -> Self {
231 Self(self.0.wrapping_add(other.0))
232 }
233
234 #[must_use = "this returns the result of the operation, without modifying the original"]
235 #[inline]
236 pub fn wrapping_sub(self, other: Self) -> Self {
237 Self(self.0.wrapping_sub(other.0))
238 }
239
240 #[must_use = "this returns the result of the operation, without modifying the original"]
241 #[inline]
242 pub fn wrapping_mul(self, other: Self) -> Self {
243 Self(self.0.wrapping_mul(other.0))
244 }
245
246 #[must_use = "this returns the result of the operation, without modifying the original"]
247 #[inline]
248 pub fn wrapping_pow(self, other: u32) -> Self {
249 Self(self.0.wrapping_pow(other))
250 }
251
252 #[must_use = "this returns the result of the operation, without modifying the original"]
253 pub fn saturating_add(self, other: Self) -> Self {
254 Self(self.0.saturating_add(other.0))
255 }
256
257 #[must_use = "this returns the result of the operation, without modifying the original"]
258 pub fn saturating_sub(self, other: Self) -> Self {
259 Self(self.0.saturating_sub(other.0))
260 }
261
262 #[must_use = "this returns the result of the operation, without modifying the original"]
263 pub fn saturating_mul(self, other: Self) -> Self {
264 Self(self.0.saturating_mul(other.0))
265 }
266
267 #[must_use = "this returns the result of the operation, without modifying the original"]
268 pub fn saturating_pow(self, exp: u32) -> Self {
269 Self(self.0.saturating_pow(exp))
270 }
271
272 #[must_use = "this returns the result of the operation, without modifying the original"]
276 pub const fn strict_add(self, rhs: Self) -> Self {
277 match self.0.checked_add(rhs.u128()) {
278 None => panic!("attempt to add with overflow"),
279 Some(sum) => Self(sum),
280 }
281 }
282
283 #[must_use = "this returns the result of the operation, without modifying the original"]
287 pub const fn strict_sub(self, other: Self) -> Self {
288 match self.0.checked_sub(other.u128()) {
289 None => panic!("attempt to subtract with overflow"),
290 Some(diff) => Self(diff),
291 }
292 }
293
294 #[must_use = "this returns the result of the operation, without modifying the original"]
295 pub const fn abs_diff(self, other: Self) -> Self {
296 Self(if self.0 < other.0 {
297 other.0 - self.0
298 } else {
299 self.0 - other.0
300 })
301 }
302}
303
304impl NumConsts for Uint128 {
305 const ZERO: Self = Self::zero();
306 const ONE: Self = Self::one();
307 const MAX: Self = Self::MAX;
308 const MIN: Self = Self::MIN;
309}
310
311impl_mul_fraction!(Uint128);
312
313primitive_to_wrapped_int!(u8, Uint128);
320primitive_to_wrapped_int!(u16, Uint128);
321primitive_to_wrapped_int!(u32, Uint128);
322primitive_to_wrapped_int!(u64, Uint128);
323primitive_to_wrapped_int!(u128, Uint128);
324
325wrapped_int_to_primitive!(Uint128, u128);
327
328impl From<Uint64> for Uint128 {
329 fn from(val: Uint64) -> Self {
330 val.u64().into()
331 }
332}
333
334forward_try_from!(Uint128, Uint64);
335
336forward_try_from!(Int64, Uint128);
338forward_try_from!(Int128, Uint128);
339forward_try_from!(Int256, Uint128);
340forward_try_from!(Int512, Uint128);
341
342impl TryFrom<&str> for Uint128 {
343 type Error = StdError;
344
345 fn try_from(val: &str) -> Result<Self, Self::Error> {
346 Self::from_str(val)
347 }
348}
349
350impl FromStr for Uint128 {
351 type Err = StdError;
352
353 fn from_str(s: &str) -> Result<Self, Self::Err> {
354 match s.parse::<u128>() {
355 Ok(u) => Ok(Uint128(u)),
356 Err(e) => Err(StdError::generic_err(format!("Parsing u128: {e}"))),
357 }
358 }
359}
360
361impl From<Uint128> for String {
362 fn from(original: Uint128) -> Self {
363 original.to_string()
364 }
365}
366
367impl fmt::Display for Uint128 {
368 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
369 self.0.fmt(f)
370 }
371}
372
373impl Add<Uint128> for Uint128 {
374 type Output = Self;
375
376 fn add(self, rhs: Self) -> Self {
377 self.strict_add(rhs)
378 }
379}
380forward_ref_binop!(impl Add, add for Uint128, Uint128);
381
382impl Sub<Uint128> for Uint128 {
383 type Output = Self;
384
385 fn sub(self, rhs: Self) -> Self {
386 self.strict_sub(rhs)
387 }
388}
389forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
390
391impl SubAssign<Uint128> for Uint128 {
392 fn sub_assign(&mut self, rhs: Uint128) {
393 *self = *self - rhs;
394 }
395}
396forward_ref_op_assign!(impl SubAssign, sub_assign for Uint128, Uint128);
397
398impl Mul<Uint128> for Uint128 {
399 type Output = Self;
400
401 fn mul(self, rhs: Self) -> Self::Output {
402 Self(
403 self.u128()
404 .checked_mul(rhs.u128())
405 .expect("attempt to multiply with overflow"),
406 )
407 }
408}
409forward_ref_binop!(impl Mul, mul for Uint128, Uint128);
410
411impl MulAssign<Uint128> for Uint128 {
412 fn mul_assign(&mut self, rhs: Self) {
413 *self = *self * rhs;
414 }
415}
416forward_ref_op_assign!(impl MulAssign, mul_assign for Uint128, Uint128);
417
418impl Div<Uint128> for Uint128 {
419 type Output = Self;
420
421 fn div(self, rhs: Self) -> Self::Output {
422 Self(
423 self.u128()
424 .checked_div(rhs.u128())
425 .expect("attempt to divide by zero"),
426 )
427 }
428}
429
430impl<'a> Div<&'a Uint128> for Uint128 {
431 type Output = Self;
432
433 fn div(self, rhs: &'a Uint128) -> Self::Output {
434 self / *rhs
435 }
436}
437
438impl Shr<u32> for Uint128 {
439 type Output = Self;
440
441 fn shr(self, rhs: u32) -> Self::Output {
442 Self(
443 self.u128()
444 .checked_shr(rhs)
445 .expect("attempt to shift right with overflow"),
446 )
447 }
448}
449
450impl<'a> Shr<&'a u32> for Uint128 {
451 type Output = Self;
452
453 fn shr(self, rhs: &'a u32) -> Self::Output {
454 self >> *rhs
455 }
456}
457
458impl Shl<u32> for Uint128 {
459 type Output = Self;
460
461 fn shl(self, rhs: u32) -> Self::Output {
462 Self(
463 self.u128()
464 .checked_shl(rhs)
465 .expect("attempt to shift left with overflow"),
466 )
467 }
468}
469
470impl<'a> Shl<&'a u32> for Uint128 {
471 type Output = Self;
472
473 fn shl(self, rhs: &'a u32) -> Self::Output {
474 self.shl(*rhs)
475 }
476}
477
478impl AddAssign<Uint128> for Uint128 {
479 fn add_assign(&mut self, rhs: Uint128) {
480 *self = *self + rhs;
481 }
482}
483
484impl<'a> AddAssign<&'a Uint128> for Uint128 {
485 fn add_assign(&mut self, rhs: &'a Uint128) {
486 *self = *self + rhs;
487 }
488}
489
490impl DivAssign<Uint128> for Uint128 {
491 fn div_assign(&mut self, rhs: Self) {
492 *self = *self / rhs;
493 }
494}
495
496impl<'a> DivAssign<&'a Uint128> for Uint128 {
497 fn div_assign(&mut self, rhs: &'a Uint128) {
498 *self = *self / rhs;
499 }
500}
501
502impl Rem for Uint128 {
503 type Output = Self;
504
505 #[inline]
509 fn rem(self, rhs: Self) -> Self {
510 Self(self.0.rem(rhs.0))
511 }
512}
513forward_ref_binop!(impl Rem, rem for Uint128, Uint128);
514
515impl Not for Uint128 {
516 type Output = Self;
517
518 fn not(self) -> Self::Output {
519 Self(!self.0)
520 }
521}
522
523impl RemAssign<Uint128> for Uint128 {
524 fn rem_assign(&mut self, rhs: Uint128) {
525 *self = *self % rhs;
526 }
527}
528forward_ref_op_assign!(impl RemAssign, rem_assign for Uint128, Uint128);
529
530impl ShrAssign<u32> for Uint128 {
531 fn shr_assign(&mut self, rhs: u32) {
532 *self = *self >> rhs;
533 }
534}
535
536impl<'a> ShrAssign<&'a u32> for Uint128 {
537 fn shr_assign(&mut self, rhs: &'a u32) {
538 *self = *self >> rhs;
539 }
540}
541
542impl ShlAssign<u32> for Uint128 {
543 fn shl_assign(&mut self, rhs: u32) {
544 *self = Shl::<u32>::shl(*self, rhs);
545 }
546}
547
548impl<'a> ShlAssign<&'a u32> for Uint128 {
549 fn shl_assign(&mut self, rhs: &'a u32) {
550 *self = Shl::<u32>::shl(*self, *rhs);
551 }
552}
553
554impl<A> core::iter::Sum<A> for Uint128
555where
556 Self: Add<A, Output = Self>,
557{
558 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
559 iter.fold(Self::zero(), Add::add)
560 }
561}
562
563#[cfg(test)]
564mod tests {
565 use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero};
566 use crate::math::conversion::test_try_from_int_to_uint;
567 use crate::{ConversionOverflowError, Decimal};
568
569 use super::*;
570
571 #[test]
572 fn size_of_works() {
573 assert_eq!(core::mem::size_of::<Uint128>(), 16);
574 }
575
576 #[test]
577 fn uint128_not_works() {
578 assert_eq!(!Uint128::new(1234806), Uint128::new(!1234806));
579
580 assert_eq!(!Uint128::MAX, Uint128::new(!u128::MAX));
581 assert_eq!(!Uint128::MIN, Uint128::new(!u128::MIN));
582 }
583
584 #[test]
585 fn uint128_zero_works() {
586 let zero = Uint128::zero();
587 assert_eq!(
588 zero.to_be_bytes(),
589 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
590 );
591 }
592
593 #[test]
594 fn uint128_one_works() {
595 let one = Uint128::one();
596 assert_eq!(
597 one.to_be_bytes(),
598 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
599 );
600 }
601
602 #[test]
603 fn uint128_from_be_bytes_works() {
604 let original = [0; 16];
606 let num = Uint128::from_be_bytes(original);
607 assert!(num.is_zero());
608
609 let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
611 let num = Uint128::from_be_bytes(original);
612 assert_eq!(num.u128(), 1);
613
614 let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2];
616 let num = Uint128::from_be_bytes(original);
617 assert_eq!(num.u128(), 258);
618
619 let original = [1; 16];
621 let num = Uint128::from_be_bytes(original);
622 let a: [u8; 16] = num.to_be_bytes();
623 assert_eq!(a, original);
624
625 let original = [
626 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
627 ];
628 let num = Uint128::from_be_bytes(original);
629 let resulting_bytes: [u8; 16] = num.to_be_bytes();
630 assert_eq!(resulting_bytes, original);
631 }
632
633 #[test]
634 fn uint128_from_le_bytes_works() {
635 let original = [0; 16];
637 let num = Uint128::from_le_bytes(original);
638 assert!(num.is_zero());
639
640 let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
642 let num = Uint128::from_le_bytes(original);
643 assert_eq!(num.u128(), 1);
644
645 let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
647 let num = Uint128::from_le_bytes(original);
648 assert_eq!(num.u128(), 258);
649
650 let original = [1; 16];
652 let num = Uint128::from_le_bytes(original);
653 let a: [u8; 16] = num.to_le_bytes();
654 assert_eq!(a, original);
655
656 let original = [
657 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
658 ];
659 let num = Uint128::from_le_bytes(original);
660 let resulting_bytes: [u8; 16] = num.to_le_bytes();
661 assert_eq!(resulting_bytes, original);
662 }
663
664 #[test]
665 fn uint128_convert_into() {
666 let original = Uint128(12345);
667 let a = u128::from(original);
668 assert_eq!(a, 12345);
669
670 let original = Uint128(12345);
671 let a = String::from(original);
672 assert_eq!(a, "12345");
673 }
674
675 #[test]
676 fn uint128_convert_from() {
677 let a = Uint128::from(5u128);
678 assert_eq!(a.0, 5);
679
680 let a = Uint128::from(5u64);
681 assert_eq!(a.0, 5);
682
683 let a = Uint128::from(5u32);
684 assert_eq!(a.0, 5);
685
686 let a = Uint128::from(5u16);
687 assert_eq!(a.0, 5);
688
689 let a = Uint128::from(5u8);
690 assert_eq!(a.0, 5);
691
692 let result = Uint128::try_from("34567");
693 assert_eq!(result.unwrap().0, 34567);
694
695 let result = Uint128::try_from("1.23");
696 assert!(result.is_err());
697 }
698
699 #[test]
700 fn uint128_try_from_signed_works() {
701 test_try_from_int_to_uint::<Int64, Uint128>("Int64", "Uint128");
702 test_try_from_int_to_uint::<Int128, Uint128>("Int128", "Uint128");
703 test_try_from_int_to_uint::<Int256, Uint128>("Int256", "Uint128");
704 test_try_from_int_to_uint::<Int512, Uint128>("Int512", "Uint128");
705 }
706
707 #[test]
708 fn uint128_try_into() {
709 assert!(Uint64::try_from(Uint128::MAX).is_err());
710
711 assert_eq!(Uint64::try_from(Uint128::zero()), Ok(Uint64::zero()));
712
713 assert_eq!(
714 Uint64::try_from(Uint128::from(42u64)),
715 Ok(Uint64::from(42u64))
716 );
717 }
718
719 #[test]
720 fn uint128_implements_display() {
721 let a = Uint128(12345);
722 assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
723 assert_eq!(a.to_string(), "12345");
724
725 let a = Uint128(0);
726 assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
727 assert_eq!(a.to_string(), "0");
728 }
729
730 #[test]
731 fn uint128_display_padding_works() {
732 let a = Uint128::from(123u64);
734 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
735
736 let a = Uint128::from(123u64);
738 assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
739 }
740
741 #[test]
742 fn uint128_to_be_bytes_works() {
743 assert_eq!(
744 Uint128::zero().to_be_bytes(),
745 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
746 );
747 assert_eq!(
748 Uint128::MAX.to_be_bytes(),
749 [
750 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
751 0xff, 0xff
752 ]
753 );
754 assert_eq!(
755 Uint128::new(1).to_be_bytes(),
756 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
757 );
758 assert_eq!(
760 Uint128::new(240282366920938463463374607431768124608).to_be_bytes(),
761 [180, 196, 179, 87, 165, 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192]
762 );
763 }
764
765 #[test]
766 fn uint128_to_le_bytes_works() {
767 assert_eq!(
768 Uint128::zero().to_le_bytes(),
769 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
770 );
771 assert_eq!(
772 Uint128::MAX.to_le_bytes(),
773 [
774 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
775 0xff, 0xff
776 ]
777 );
778 assert_eq!(
779 Uint128::new(1).to_le_bytes(),
780 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
781 );
782 assert_eq!(
784 Uint128::new(240282366920938463463374607431768124608).to_le_bytes(),
785 [192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180]
786 );
787 }
788
789 #[test]
790 fn uint128_is_zero_works() {
791 assert!(Uint128::zero().is_zero());
792 assert!(Uint128(0).is_zero());
793
794 assert!(!Uint128(1).is_zero());
795 assert!(!Uint128(123).is_zero());
796 }
797
798 #[test]
799 fn uint128_json() {
800 let orig = Uint128(1234567890987654321);
801 let serialized = serde_json::to_vec(&orig).unwrap();
802 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
803 let parsed: Uint128 = serde_json::from_slice(&serialized).unwrap();
804 assert_eq!(parsed, orig);
805 }
806
807 #[test]
808 fn uint128_compare() {
809 let a = Uint128(12345);
810 let b = Uint128(23456);
811
812 assert!(a < b);
813 assert!(b > a);
814 assert_eq!(a, Uint128(12345));
815 }
816
817 #[test]
818 #[allow(clippy::op_ref)]
819 fn uint128_math() {
820 let a = Uint128(12345);
821 let b = Uint128(23456);
822
823 assert_eq!(b - a, Uint128(11111));
825 assert_eq!(b - &a, Uint128(11111));
826
827 let mut c = Uint128(300000);
829 c += b;
830 assert_eq!(c, Uint128(323456));
831 let mut d = Uint128(300000);
832 d += &b;
833 assert_eq!(d, Uint128(323456));
834
835 let mut c = Uint128(300000);
837 c -= b;
838 assert_eq!(c, Uint128(276544));
839 let mut d = Uint128(300000);
840 d -= &b;
841 assert_eq!(d, Uint128(276544));
842
843 let underflow_result = a.checked_sub(b);
845 let OverflowError { operation } = underflow_result.unwrap_err();
846 assert_eq!(operation, OverflowOperation::Sub);
847 }
848
849 #[test]
850 #[allow(clippy::op_ref)]
851 fn uint128_add_works() {
852 assert_eq!(
853 Uint128::from(2u32) + Uint128::from(1u32),
854 Uint128::from(3u32)
855 );
856 assert_eq!(
857 Uint128::from(2u32) + Uint128::from(0u32),
858 Uint128::from(2u32)
859 );
860
861 let a = Uint128::from(10u32);
863 let b = Uint128::from(3u32);
864 let expected = Uint128::from(13u32);
865 assert_eq!(a + b, expected);
866 assert_eq!(a + &b, expected);
867 assert_eq!(&a + b, expected);
868 assert_eq!(&a + &b, expected);
869 }
870
871 #[test]
872 #[should_panic(expected = "attempt to add with overflow")]
873 fn uint128_add_overflow_panics() {
874 let max = Uint128::MAX;
875 let _ = max + Uint128(12);
876 }
877
878 #[test]
879 #[allow(clippy::op_ref)]
880 fn uint128_sub_works() {
881 assert_eq!(Uint128(2) - Uint128(1), Uint128(1));
882 assert_eq!(Uint128(2) - Uint128(0), Uint128(2));
883 assert_eq!(Uint128(2) - Uint128(2), Uint128(0));
884
885 let a = Uint128::new(10);
887 let b = Uint128::new(3);
888 let expected = Uint128::new(7);
889 assert_eq!(a - b, expected);
890 assert_eq!(a - &b, expected);
891 assert_eq!(&a - b, expected);
892 assert_eq!(&a - &b, expected);
893 }
894
895 #[test]
896 #[should_panic]
897 fn uint128_sub_overflow_panics() {
898 let _ = Uint128(1) - Uint128(2);
899 }
900
901 #[test]
902 fn uint128_sub_assign_works() {
903 let mut a = Uint128(14);
904 a -= Uint128(2);
905 assert_eq!(a, Uint128(12));
906
907 let mut a = Uint128::new(10);
909 let b = Uint128::new(3);
910 let expected = Uint128::new(7);
911 a -= &b;
912 assert_eq!(a, expected);
913 }
914
915 #[test]
916 #[allow(clippy::op_ref)]
917 fn uint128_mul_works() {
918 assert_eq!(
919 Uint128::from(2u32) * Uint128::from(3u32),
920 Uint128::from(6u32)
921 );
922 assert_eq!(Uint128::from(2u32) * Uint128::zero(), Uint128::zero());
923
924 let a = Uint128::from(11u32);
926 let b = Uint128::from(3u32);
927 let expected = Uint128::from(33u32);
928 assert_eq!(a * b, expected);
929 assert_eq!(a * &b, expected);
930 assert_eq!(&a * b, expected);
931 assert_eq!(&a * &b, expected);
932 }
933
934 #[test]
935 fn uint128_mul_assign_works() {
936 let mut a = Uint128::from(14u32);
937 a *= Uint128::from(2u32);
938 assert_eq!(a, Uint128::from(28u32));
939
940 let mut a = Uint128::from(10u32);
942 let b = Uint128::from(3u32);
943 a *= &b;
944 assert_eq!(a, Uint128::from(30u32));
945 }
946
947 #[test]
948 fn uint128_pow_works() {
949 assert_eq!(Uint128::from(2u32).pow(2), Uint128::from(4u32));
950 assert_eq!(Uint128::from(2u32).pow(10), Uint128::from(1024u32));
951 }
952
953 #[test]
954 #[should_panic]
955 fn uint128_pow_overflow_panics() {
956 _ = Uint128::MAX.pow(2u32);
957 }
958
959 #[test]
960 fn uint128_multiply_ratio_works() {
961 let base = Uint128(500);
962
963 assert_eq!(base.multiply_ratio(1u128, 1u128), base);
965 assert_eq!(base.multiply_ratio(3u128, 3u128), base);
966 assert_eq!(base.multiply_ratio(654321u128, 654321u128), base);
967 assert_eq!(base.multiply_ratio(u128::MAX, u128::MAX), base);
968
969 assert_eq!(base.multiply_ratio(3u128, 2u128), Uint128(750));
971 assert_eq!(base.multiply_ratio(333333u128, 222222u128), Uint128(750));
972
973 assert_eq!(base.multiply_ratio(2u128, 3u128), Uint128(333));
975 assert_eq!(base.multiply_ratio(222222u128, 333333u128), Uint128(333));
976
977 assert_eq!(base.multiply_ratio(5u128, 6u128), Uint128(416));
979 assert_eq!(base.multiply_ratio(100u128, 120u128), Uint128(416));
980 }
981
982 #[test]
983 fn uint128_multiply_ratio_does_not_overflow_when_result_fits() {
984 let base = Uint128(u128::MAX - 9);
986
987 assert_eq!(base.multiply_ratio(2u128, 2u128), base);
988 }
989
990 #[test]
991 #[should_panic]
992 fn uint128_multiply_ratio_panicks_on_overflow() {
993 let base = Uint128(u128::MAX - 9);
995
996 assert_eq!(base.multiply_ratio(2u128, 1u128), base);
997 }
998
999 #[test]
1000 #[should_panic(expected = "Denominator must not be zero")]
1001 fn uint128_multiply_ratio_panics_for_zero_denominator() {
1002 _ = Uint128(500).multiply_ratio(1u128, 0u128);
1003 }
1004
1005 #[test]
1006 fn uint128_checked_multiply_ratio_does_not_panic() {
1007 assert_eq!(
1008 Uint128(500u128).checked_multiply_ratio(1u128, 0u128),
1009 Err(CheckedMultiplyRatioError::DivideByZero),
1010 );
1011 assert_eq!(
1012 Uint128(500u128).checked_multiply_ratio(u128::MAX, 1u128),
1013 Err(CheckedMultiplyRatioError::Overflow),
1014 );
1015 }
1016
1017 #[test]
1018 fn uint128_shr_works() {
1019 let original = Uint128::new(u128::from_be_bytes([
1020 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1021 ]));
1022
1023 let shifted = Uint128::new(u128::from_be_bytes([
1024 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1025 ]));
1026
1027 assert_eq!(original >> 2u32, shifted);
1028 }
1029
1030 #[test]
1031 #[should_panic]
1032 fn uint128_shr_overflow_panics() {
1033 let _ = Uint128::from(1u32) >> 128u32;
1034 }
1035
1036 #[test]
1037 fn uint128_shl_works() {
1038 let original = Uint128::new(u128::from_be_bytes([
1039 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1040 ]));
1041
1042 let shifted = Uint128::new(u128::from_be_bytes([
1043 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1044 ]));
1045
1046 assert_eq!(original << 2u32, shifted);
1047 }
1048
1049 #[test]
1050 #[should_panic]
1051 fn uint128_shl_overflow_panics() {
1052 let _ = Uint128::from(1u32) << 128u32;
1053 }
1054
1055 #[test]
1056 fn sum_works() {
1057 let nums = vec![Uint128(17), Uint128(123), Uint128(540), Uint128(82)];
1058 let expected = Uint128(762);
1059
1060 let sum_as_ref: Uint128 = nums.iter().sum();
1061 assert_eq!(expected, sum_as_ref);
1062
1063 let sum_as_owned: Uint128 = nums.into_iter().sum();
1064 assert_eq!(expected, sum_as_owned);
1065 }
1066
1067 #[test]
1068 fn uint128_methods() {
1069 assert!(matches!(
1071 Uint128::MAX.checked_add(Uint128(1)),
1072 Err(OverflowError { .. })
1073 ));
1074 assert!(matches!(Uint128(1).checked_add(Uint128(1)), Ok(Uint128(2))));
1075 assert!(matches!(
1076 Uint128(0).checked_sub(Uint128(1)),
1077 Err(OverflowError { .. })
1078 ));
1079 assert!(matches!(Uint128(2).checked_sub(Uint128(1)), Ok(Uint128(1))));
1080 assert!(matches!(
1081 Uint128::MAX.checked_mul(Uint128(2)),
1082 Err(OverflowError { .. })
1083 ));
1084 assert!(matches!(Uint128(2).checked_mul(Uint128(2)), Ok(Uint128(4))));
1085 assert!(matches!(
1086 Uint128::MAX.checked_pow(2u32),
1087 Err(OverflowError { .. })
1088 ));
1089 assert!(matches!(Uint128(2).checked_pow(3), Ok(Uint128(8))));
1090 assert!(matches!(
1091 Uint128::MAX.checked_div(Uint128(0)),
1092 Err(DivideByZeroError { .. })
1093 ));
1094 assert!(matches!(Uint128(6).checked_div(Uint128(2)), Ok(Uint128(3))));
1095 assert!(matches!(
1096 Uint128::MAX.checked_div_euclid(Uint128(0)),
1097 Err(DivideByZeroError { .. })
1098 ));
1099 assert!(matches!(
1100 Uint128(6).checked_div_euclid(Uint128(2)),
1101 Ok(Uint128(3)),
1102 ));
1103 assert!(matches!(
1104 Uint128::MAX.checked_rem(Uint128(0)),
1105 Err(DivideByZeroError { .. })
1106 ));
1107
1108 assert_eq!(Uint128::MAX.saturating_add(Uint128(1)), Uint128::MAX);
1110 assert_eq!(Uint128(0).saturating_sub(Uint128(1)), Uint128(0));
1111 assert_eq!(Uint128::MAX.saturating_mul(Uint128(2)), Uint128::MAX);
1112 assert_eq!(Uint128::MAX.saturating_pow(2), Uint128::MAX);
1113 }
1114
1115 #[test]
1116 fn uint128_wrapping_methods() {
1117 assert_eq!(Uint128(2).wrapping_add(Uint128(2)), Uint128(4)); assert_eq!(Uint128::MAX.wrapping_add(Uint128(1)), Uint128(0)); assert_eq!(Uint128(7).wrapping_sub(Uint128(5)), Uint128(2)); assert_eq!(Uint128(0).wrapping_sub(Uint128(1)), Uint128::MAX); assert_eq!(Uint128(3).wrapping_mul(Uint128(2)), Uint128(6)); assert_eq!(
1128 Uint128::MAX.wrapping_mul(Uint128(2)),
1129 Uint128::MAX - Uint128::one()
1130 ); assert_eq!(Uint128(2).wrapping_pow(3), Uint128(8)); assert_eq!(Uint128::MAX.wrapping_pow(2), Uint128(1)); }
1136
1137 #[test]
1138 #[allow(clippy::op_ref)]
1139 fn uint128_implements_rem() {
1140 let a = Uint128::new(10);
1141 assert_eq!(a % Uint128::new(10), Uint128::zero());
1142 assert_eq!(a % Uint128::new(2), Uint128::zero());
1143 assert_eq!(a % Uint128::new(1), Uint128::zero());
1144 assert_eq!(a % Uint128::new(3), Uint128::new(1));
1145 assert_eq!(a % Uint128::new(4), Uint128::new(2));
1146
1147 let a = Uint128::new(10);
1149 let b = Uint128::new(3);
1150 let expected = Uint128::new(1);
1151 assert_eq!(a % b, expected);
1152 assert_eq!(a % &b, expected);
1153 assert_eq!(&a % b, expected);
1154 assert_eq!(&a % &b, expected);
1155 }
1156
1157 #[test]
1158 #[should_panic(expected = "divisor of zero")]
1159 fn uint128_rem_panics_for_zero() {
1160 let _ = Uint128::new(10) % Uint128::zero();
1161 }
1162
1163 #[test]
1164 #[allow(clippy::op_ref)]
1165 fn uint128_rem_works() {
1166 assert_eq!(
1167 Uint128::from(12u32) % Uint128::from(10u32),
1168 Uint128::from(2u32)
1169 );
1170 assert_eq!(Uint128::from(50u32) % Uint128::from(5u32), Uint128::zero());
1171
1172 let a = Uint128::from(42u32);
1174 let b = Uint128::from(5u32);
1175 let expected = Uint128::from(2u32);
1176 assert_eq!(a % b, expected);
1177 assert_eq!(a % &b, expected);
1178 assert_eq!(&a % b, expected);
1179 assert_eq!(&a % &b, expected);
1180 }
1181
1182 #[test]
1183 fn uint128_rem_assign_works() {
1184 let mut a = Uint128::from(30u32);
1185 a %= Uint128::from(4u32);
1186 assert_eq!(a, Uint128::from(2u32));
1187
1188 let mut a = Uint128::from(25u32);
1190 let b = Uint128::from(6u32);
1191 a %= &b;
1192 assert_eq!(a, Uint128::from(1u32));
1193 }
1194
1195 #[test]
1196 fn uint128_strict_add_works() {
1197 let a = Uint128::new(5);
1198 let b = Uint128::new(3);
1199 assert_eq!(a.strict_add(b), Uint128::new(8));
1200 assert_eq!(b.strict_add(a), Uint128::new(8));
1201 }
1202
1203 #[test]
1204 #[should_panic(expected = "attempt to add with overflow")]
1205 fn uint128_strict_add_panics_on_overflow() {
1206 let a = Uint128::MAX;
1207 let b = Uint128::ONE;
1208 let _ = a.strict_add(b);
1209 }
1210
1211 #[test]
1212 fn uint128_strict_sub_works() {
1213 let a = Uint128::new(5);
1214 let b = Uint128::new(3);
1215 assert_eq!(a.strict_sub(b), Uint128::new(2));
1216 }
1217
1218 #[test]
1219 #[should_panic(expected = "attempt to subtract with overflow")]
1220 fn uint128_strict_sub_panics_on_overflow() {
1221 let a = Uint128::ZERO;
1222 let b = Uint128::ONE;
1223 let _ = a.strict_sub(b);
1224 }
1225
1226 #[test]
1227 fn uint128_abs_diff_works() {
1228 let a = Uint128::from(42u32);
1229 let b = Uint128::from(5u32);
1230 let expected = Uint128::from(37u32);
1231 assert_eq!(a.abs_diff(b), expected);
1232 assert_eq!(b.abs_diff(a), expected);
1233 }
1234
1235 #[test]
1236 fn uint128_partial_eq() {
1237 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1238 .into_iter()
1239 .map(|(lhs, rhs, expected)| (Uint128::new(lhs), Uint128::new(rhs), expected));
1240
1241 #[allow(clippy::op_ref)]
1242 for (lhs, rhs, expected) in test_cases {
1243 assert_eq!(lhs == rhs, expected);
1244 assert_eq!(&lhs == rhs, expected);
1245 assert_eq!(lhs == &rhs, expected);
1246 assert_eq!(&lhs == &rhs, expected);
1247 }
1248 }
1249
1250 #[test]
1251 fn mul_floor_works_with_zero() {
1252 let fraction = (Uint128::zero(), Uint128::new(21));
1253 let res = Uint128::new(123456).mul_floor(fraction);
1254 assert_eq!(Uint128::zero(), res)
1255 }
1256
1257 #[test]
1258 fn mul_floor_does_nothing_with_one() {
1259 let fraction = (Uint128::one(), Uint128::one());
1260 let res = Uint128::new(123456).mul_floor(fraction);
1261 assert_eq!(Uint128::new(123456), res)
1262 }
1263
1264 #[test]
1265 fn mul_floor_rounds_down_with_normal_case() {
1266 let fraction = (8u128, 21u128);
1267 let res = Uint128::new(123456).mul_floor(fraction); assert_eq!(Uint128::new(47030), res)
1269 }
1270
1271 #[test]
1272 fn mul_floor_does_not_round_on_even_divide() {
1273 let fraction = (2u128, 5u128);
1274 let res = Uint128::new(25).mul_floor(fraction);
1275 assert_eq!(Uint128::new(10), res)
1276 }
1277
1278 #[test]
1279 fn mul_floor_works_when_operation_temporarily_takes_above_max() {
1280 let fraction = (8u128, 21u128);
1281 let res = Uint128::MAX.mul_floor(fraction); assert_eq!(
1283 Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697),
1284 res
1285 )
1286 }
1287
1288 #[test]
1289 fn mul_floor_works_with_decimal() {
1290 let decimal = Decimal::from_ratio(8u128, 21u128);
1291 let res = Uint128::new(123456).mul_floor(decimal); assert_eq!(Uint128::new(47030), res)
1293 }
1294
1295 #[test]
1296 #[should_panic(expected = "ConversionOverflowError")]
1297 fn mul_floor_panics_on_overflow() {
1298 let fraction = (21u128, 8u128);
1299 _ = Uint128::MAX.mul_floor(fraction);
1300 }
1301
1302 #[test]
1303 fn checked_mul_floor_does_not_panic_on_overflow() {
1304 let fraction = (21u128, 8u128);
1305 assert_eq!(
1306 Uint128::MAX.checked_mul_floor(fraction),
1307 Err(ConversionOverflow(ConversionOverflowError {
1308 source_type: "Uint256",
1309 target_type: "Uint128",
1310 })),
1311 );
1312 }
1313
1314 #[test]
1315 #[should_panic(expected = "DivideByZeroError")]
1316 fn mul_floor_panics_on_zero_div() {
1317 let fraction = (21u128, 0u128);
1318 _ = Uint128::new(123456).mul_floor(fraction);
1319 }
1320
1321 #[test]
1322 fn checked_mul_floor_does_not_panic_on_zero_div() {
1323 let fraction = (21u128, 0u128);
1324 assert_eq!(
1325 Uint128::new(123456).checked_mul_floor(fraction),
1326 Err(DivideByZero(DivideByZeroError)),
1327 );
1328 }
1329
1330 #[test]
1331 fn mul_ceil_works_with_zero() {
1332 let fraction = (Uint128::zero(), Uint128::new(21));
1333 let res = Uint128::new(123456).mul_ceil(fraction);
1334 assert_eq!(Uint128::zero(), res)
1335 }
1336
1337 #[test]
1338 fn mul_ceil_does_nothing_with_one() {
1339 let fraction = (Uint128::one(), Uint128::one());
1340 let res = Uint128::new(123456).mul_ceil(fraction);
1341 assert_eq!(Uint128::new(123456), res)
1342 }
1343
1344 #[test]
1345 fn mul_ceil_rounds_up_with_normal_case() {
1346 let fraction = (8u128, 21u128);
1347 let res = Uint128::new(123456).mul_ceil(fraction); assert_eq!(Uint128::new(47031), res)
1349 }
1350
1351 #[test]
1352 fn mul_ceil_does_not_round_on_even_divide() {
1353 let fraction = (2u128, 5u128);
1354 let res = Uint128::new(25).mul_ceil(fraction);
1355 assert_eq!(Uint128::new(10), res)
1356 }
1357
1358 #[test]
1359 fn mul_ceil_works_when_operation_temporarily_takes_above_max() {
1360 let fraction = (8u128, 21u128);
1361 let res = Uint128::MAX.mul_ceil(fraction); assert_eq!(
1363 Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698),
1364 res
1365 )
1366 }
1367
1368 #[test]
1369 fn mul_ceil_works_with_decimal() {
1370 let decimal = Decimal::from_ratio(8u128, 21u128);
1371 let res = Uint128::new(123456).mul_ceil(decimal); assert_eq!(Uint128::new(47031), res)
1373 }
1374
1375 #[test]
1376 #[should_panic(expected = "ConversionOverflowError")]
1377 fn mul_ceil_panics_on_overflow() {
1378 let fraction = (21u128, 8u128);
1379 _ = Uint128::MAX.mul_ceil(fraction);
1380 }
1381
1382 #[test]
1383 fn checked_mul_ceil_does_not_panic_on_overflow() {
1384 let fraction = (21u128, 8u128);
1385 assert_eq!(
1386 Uint128::MAX.checked_mul_ceil(fraction),
1387 Err(ConversionOverflow(ConversionOverflowError {
1388 source_type: "Uint256",
1389 target_type: "Uint128",
1390 })),
1391 );
1392 }
1393
1394 #[test]
1395 #[should_panic(expected = "DivideByZeroError")]
1396 fn mul_ceil_panics_on_zero_div() {
1397 let fraction = (21u128, 0u128);
1398 _ = Uint128::new(123456).mul_ceil(fraction);
1399 }
1400
1401 #[test]
1402 fn checked_mul_ceil_does_not_panic_on_zero_div() {
1403 let fraction = (21u128, 0u128);
1404 assert_eq!(
1405 Uint128::new(123456).checked_mul_ceil(fraction),
1406 Err(DivideByZero(DivideByZeroError)),
1407 );
1408 }
1409
1410 #[test]
1411 #[should_panic(expected = "DivideByZeroError")]
1412 fn div_floor_raises_with_zero() {
1413 let fraction = (Uint128::zero(), Uint128::new(21));
1414 _ = Uint128::new(123456).div_floor(fraction);
1415 }
1416
1417 #[test]
1418 fn div_floor_does_nothing_with_one() {
1419 let fraction = (Uint128::one(), Uint128::one());
1420 let res = Uint128::new(123456).div_floor(fraction);
1421 assert_eq!(Uint128::new(123456), res)
1422 }
1423
1424 #[test]
1425 fn div_floor_rounds_down_with_normal_case() {
1426 let fraction = (5u128, 21u128);
1427 let res = Uint128::new(123456).div_floor(fraction); assert_eq!(Uint128::new(518515), res)
1429 }
1430
1431 #[test]
1432 fn div_floor_does_not_round_on_even_divide() {
1433 let fraction = (5u128, 2u128);
1434 let res = Uint128::new(25).div_floor(fraction);
1435 assert_eq!(Uint128::new(10), res)
1436 }
1437
1438 #[test]
1439 fn div_floor_works_when_operation_temporarily_takes_above_max() {
1440 let fraction = (21u128, 8u128);
1441 let res = Uint128::MAX.div_floor(fraction); assert_eq!(
1443 Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697),
1444 res
1445 )
1446 }
1447
1448 #[test]
1449 fn div_floor_works_with_decimal() {
1450 let decimal = Decimal::from_ratio(21u128, 8u128);
1451 let res = Uint128::new(123456).div_floor(decimal); assert_eq!(Uint128::new(47030), res)
1453 }
1454
1455 #[test]
1456 fn div_floor_works_with_decimal_evenly() {
1457 let res = Uint128::new(60).div_floor(Decimal::from_atomics(6u128, 0).unwrap());
1458 assert_eq!(res, Uint128::new(10));
1459 }
1460
1461 #[test]
1462 #[should_panic(expected = "ConversionOverflowError")]
1463 fn div_floor_panics_on_overflow() {
1464 let fraction = (8u128, 21u128);
1465 _ = Uint128::MAX.div_floor(fraction);
1466 }
1467
1468 #[test]
1469 fn div_floor_does_not_panic_on_overflow() {
1470 let fraction = (8u128, 21u128);
1471 assert_eq!(
1472 Uint128::MAX.checked_div_floor(fraction),
1473 Err(ConversionOverflow(ConversionOverflowError {
1474 source_type: "Uint256",
1475 target_type: "Uint128",
1476 })),
1477 );
1478 }
1479
1480 #[test]
1481 #[should_panic(expected = "DivideByZeroError")]
1482 fn div_ceil_raises_with_zero() {
1483 let fraction = (Uint128::zero(), Uint128::new(21));
1484 _ = Uint128::new(123456).div_ceil(fraction);
1485 }
1486
1487 #[test]
1488 fn div_ceil_does_nothing_with_one() {
1489 let fraction = (Uint128::one(), Uint128::one());
1490 let res = Uint128::new(123456).div_ceil(fraction);
1491 assert_eq!(Uint128::new(123456), res)
1492 }
1493
1494 #[test]
1495 fn div_ceil_rounds_up_with_normal_case() {
1496 let fraction = (5u128, 21u128);
1497 let res = Uint128::new(123456).div_ceil(fraction); assert_eq!(Uint128::new(518516), res)
1499 }
1500
1501 #[test]
1502 fn div_ceil_does_not_round_on_even_divide() {
1503 let fraction = (5u128, 2u128);
1504 let res = Uint128::new(25).div_ceil(fraction);
1505 assert_eq!(Uint128::new(10), res)
1506 }
1507
1508 #[test]
1509 fn div_ceil_works_when_operation_temporarily_takes_above_max() {
1510 let fraction = (21u128, 8u128);
1511 let res = Uint128::MAX.div_ceil(fraction); assert_eq!(
1513 Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698),
1514 res
1515 )
1516 }
1517
1518 #[test]
1519 fn div_ceil_works_with_decimal() {
1520 let decimal = Decimal::from_ratio(21u128, 8u128);
1521 let res = Uint128::new(123456).div_ceil(decimal); assert_eq!(Uint128::new(47031), res)
1523 }
1524
1525 #[test]
1526 fn div_ceil_works_with_decimal_evenly() {
1527 let res = Uint128::new(60).div_ceil(Decimal::from_atomics(6u128, 0).unwrap());
1528 assert_eq!(res, Uint128::new(10));
1529 }
1530
1531 #[test]
1532 #[should_panic(expected = "ConversionOverflowError")]
1533 fn div_ceil_panics_on_overflow() {
1534 let fraction = (8u128, 21u128);
1535 _ = Uint128::MAX.div_ceil(fraction);
1536 }
1537
1538 #[test]
1539 fn div_ceil_does_not_panic_on_overflow() {
1540 let fraction = (8u128, 21u128);
1541 assert_eq!(
1542 Uint128::MAX.checked_div_ceil(fraction),
1543 Err(ConversionOverflow(ConversionOverflowError {
1544 source_type: "Uint256",
1545 target_type: "Uint128",
1546 })),
1547 );
1548 }
1549}