1use forward_ref::{forward_ref_binop, forward_ref_op_assign};
2use schemars::JsonSchema;
3use serde::{de, ser, Deserialize, Deserializer, Serialize};
4use std::fmt::{self};
5use std::ops::{
6 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shr, ShrAssign, Sub, SubAssign,
7};
8use std::str::FromStr;
9
10use crate::errors::{
11 CheckedMultiplyRatioError, DivideByZeroError, OverflowError, OverflowOperation, StdError,
12};
13use crate::{ConversionOverflowError, Uint256, Uint64};
14
15#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
35pub struct Uint128(#[schemars(with = "String")] u128);
36
37impl Uint128 {
38 pub const MAX: Self = Self(u128::MAX);
39 pub const MIN: Self = Self(u128::MIN);
40
41 pub const fn new(value: u128) -> Self {
45 Uint128(value)
46 }
47
48 #[inline]
50 pub const fn zero() -> Self {
51 Uint128(0)
52 }
53
54 #[inline]
56 pub const fn one() -> Self {
57 Self(1)
58 }
59
60 pub const fn u128(&self) -> u128 {
62 self.0
63 }
64
65 pub const fn to_be_bytes(self) -> [u8; 16] {
67 self.0.to_be_bytes()
68 }
69
70 pub const fn to_le_bytes(self) -> [u8; 16] {
72 self.0.to_le_bytes()
73 }
74
75 pub const fn is_zero(&self) -> bool {
76 self.0 == 0
77 }
78
79 pub fn pow(self, exp: u32) -> Self {
80 self.0.pow(exp).into()
81 }
82
83 pub fn multiply_ratio<A: Into<u128>, B: Into<u128>>(
88 &self,
89 numerator: A,
90 denominator: B,
91 ) -> Uint128 {
92 match self.checked_multiply_ratio(numerator, denominator) {
93 Ok(value) => value,
94 Err(CheckedMultiplyRatioError::DivideByZero) => {
95 panic!("Denominator must not be zero")
96 }
97 Err(CheckedMultiplyRatioError::Overflow) => panic!("Multiplication overflow"),
98 }
99 }
100
101 pub fn checked_multiply_ratio<A: Into<u128>, B: Into<u128>>(
106 &self,
107 numerator: A,
108 denominator: B,
109 ) -> Result<Uint128, CheckedMultiplyRatioError> {
110 let numerator: u128 = numerator.into();
111 let denominator: u128 = denominator.into();
112 if denominator == 0 {
113 return Err(CheckedMultiplyRatioError::DivideByZero);
114 }
115 match (self.full_mul(numerator) / Uint256::from(denominator)).try_into() {
116 Ok(ratio) => Ok(ratio),
117 Err(_) => Err(CheckedMultiplyRatioError::Overflow),
118 }
119 }
120
121 pub fn full_mul(self, rhs: impl Into<u128>) -> Uint256 {
134 Uint256::from(self.u128())
135 .checked_mul(Uint256::from(rhs.into()))
136 .unwrap()
137 }
138
139 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
140 self.0
141 .checked_add(other.0)
142 .map(Self)
143 .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other))
144 }
145
146 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
147 self.0
148 .checked_sub(other.0)
149 .map(Self)
150 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other))
151 }
152
153 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
154 self.0
155 .checked_mul(other.0)
156 .map(Self)
157 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other))
158 }
159
160 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
161 self.0
162 .checked_pow(exp)
163 .map(Self)
164 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp))
165 }
166
167 pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
168 self.0
169 .checked_div(other.0)
170 .map(Self)
171 .ok_or_else(|| DivideByZeroError::new(self))
172 }
173
174 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
175 self.0
176 .checked_div_euclid(other.0)
177 .map(Self)
178 .ok_or_else(|| DivideByZeroError::new(self))
179 }
180
181 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
182 self.0
183 .checked_rem(other.0)
184 .map(Self)
185 .ok_or_else(|| DivideByZeroError::new(self))
186 }
187
188 #[inline]
189 pub fn wrapping_add(self, other: Self) -> Self {
190 Self(self.0.wrapping_add(other.0))
191 }
192
193 #[inline]
194 pub fn wrapping_sub(self, other: Self) -> Self {
195 Self(self.0.wrapping_sub(other.0))
196 }
197
198 #[inline]
199 pub fn wrapping_mul(self, other: Self) -> Self {
200 Self(self.0.wrapping_mul(other.0))
201 }
202
203 #[inline]
204 pub fn wrapping_pow(self, other: u32) -> Self {
205 Self(self.0.wrapping_pow(other))
206 }
207
208 pub fn saturating_add(self, other: Self) -> Self {
209 Self(self.0.saturating_add(other.0))
210 }
211
212 pub fn saturating_sub(self, other: Self) -> Self {
213 Self(self.0.saturating_sub(other.0))
214 }
215
216 pub fn saturating_mul(self, other: Self) -> Self {
217 Self(self.0.saturating_mul(other.0))
218 }
219
220 pub fn saturating_pow(self, exp: u32) -> Self {
221 Self(self.0.saturating_pow(exp))
222 }
223
224 pub const fn abs_diff(self, other: Self) -> Self {
225 Self(if self.0 < other.0 {
226 other.0 - self.0
227 } else {
228 self.0 - other.0
229 })
230 }
231}
232
233impl From<Uint64> for Uint128 {
239 fn from(val: Uint64) -> Self {
240 val.u64().into()
241 }
242}
243
244impl From<u128> for Uint128 {
245 fn from(val: u128) -> Self {
246 Uint128(val)
247 }
248}
249
250impl From<u64> for Uint128 {
251 fn from(val: u64) -> Self {
252 Uint128(val.into())
253 }
254}
255
256impl From<u32> for Uint128 {
257 fn from(val: u32) -> Self {
258 Uint128(val.into())
259 }
260}
261
262impl From<u16> for Uint128 {
263 fn from(val: u16) -> Self {
264 Uint128(val.into())
265 }
266}
267
268impl From<u8> for Uint128 {
269 fn from(val: u8) -> Self {
270 Uint128(val.into())
271 }
272}
273
274impl TryFrom<Uint128> for Uint64 {
275 type Error = ConversionOverflowError;
276
277 fn try_from(value: Uint128) -> Result<Self, Self::Error> {
278 Ok(Uint64::new(value.0.try_into().map_err(|_| {
279 ConversionOverflowError::new("Uint128", "Uint64", value.to_string())
280 })?))
281 }
282}
283
284impl TryFrom<&str> for Uint128 {
285 type Error = StdError;
286
287 fn try_from(val: &str) -> Result<Self, Self::Error> {
288 Self::from_str(val)
289 }
290}
291
292impl FromStr for Uint128 {
293 type Err = StdError;
294
295 fn from_str(s: &str) -> Result<Self, Self::Err> {
296 match s.parse::<u128>() {
297 Ok(u) => Ok(Uint128(u)),
298 Err(e) => Err(StdError::generic_err(format!("Parsing u128: {}", e))),
299 }
300 }
301}
302
303impl From<Uint128> for String {
304 fn from(original: Uint128) -> Self {
305 original.to_string()
306 }
307}
308
309impl From<Uint128> for u128 {
310 fn from(original: Uint128) -> Self {
311 original.0
312 }
313}
314
315impl fmt::Display for Uint128 {
316 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317 self.0.fmt(f)
318 }
319}
320
321impl Add<Uint128> for Uint128 {
322 type Output = Self;
323
324 fn add(self, rhs: Self) -> Self {
325 Uint128(
326 self.u128()
327 .checked_add(rhs.u128())
328 .expect("attempt to add with overflow"),
329 )
330 }
331}
332
333impl<'a> Add<&'a Uint128> for Uint128 {
334 type Output = Self;
335
336 fn add(self, rhs: &'a Uint128) -> Self {
337 self + *rhs
338 }
339}
340
341impl Sub<Uint128> for Uint128 {
342 type Output = Self;
343
344 fn sub(self, rhs: Self) -> Self {
345 Uint128(
346 self.u128()
347 .checked_sub(rhs.u128())
348 .expect("attempt to subtract with overflow"),
349 )
350 }
351}
352forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
353
354impl SubAssign<Uint128> for Uint128 {
355 fn sub_assign(&mut self, rhs: Uint128) {
356 *self = *self - rhs;
357 }
358}
359forward_ref_op_assign!(impl SubAssign, sub_assign for Uint128, Uint128);
360
361impl Mul<Uint128> for Uint128 {
362 type Output = Self;
363
364 fn mul(self, rhs: Self) -> Self::Output {
365 Self(
366 self.u128()
367 .checked_mul(rhs.u128())
368 .expect("attempt to multiply with overflow"),
369 )
370 }
371}
372forward_ref_binop!(impl Mul, mul for Uint128, Uint128);
373
374impl MulAssign<Uint128> for Uint128 {
375 fn mul_assign(&mut self, rhs: Self) {
376 *self = *self * rhs;
377 }
378}
379forward_ref_op_assign!(impl MulAssign, mul_assign for Uint128, Uint128);
380
381impl Div<Uint128> for Uint128 {
382 type Output = Self;
383
384 fn div(self, rhs: Self) -> Self::Output {
385 Self(
386 self.u128()
387 .checked_div(rhs.u128())
388 .expect("attempt to divide by zero"),
389 )
390 }
391}
392
393impl<'a> Div<&'a Uint128> for Uint128 {
394 type Output = Self;
395
396 fn div(self, rhs: &'a Uint128) -> Self::Output {
397 self / *rhs
398 }
399}
400
401impl Shr<u32> for Uint128 {
402 type Output = Self;
403
404 fn shr(self, rhs: u32) -> Self::Output {
405 Self(
406 self.u128()
407 .checked_shr(rhs)
408 .expect("attempt to shift right with overflow"),
409 )
410 }
411}
412
413impl<'a> Shr<&'a u32> for Uint128 {
414 type Output = Self;
415
416 fn shr(self, rhs: &'a u32) -> Self::Output {
417 self >> *rhs
418 }
419}
420
421impl AddAssign<Uint128> for Uint128 {
422 fn add_assign(&mut self, rhs: Uint128) {
423 *self = *self + rhs;
424 }
425}
426
427impl<'a> AddAssign<&'a Uint128> for Uint128 {
428 fn add_assign(&mut self, rhs: &'a Uint128) {
429 *self = *self + rhs;
430 }
431}
432
433impl DivAssign<Uint128> for Uint128 {
434 fn div_assign(&mut self, rhs: Self) {
435 *self = *self / rhs;
436 }
437}
438
439impl<'a> DivAssign<&'a Uint128> for Uint128 {
440 fn div_assign(&mut self, rhs: &'a Uint128) {
441 *self = *self / rhs;
442 }
443}
444
445impl Rem for Uint128 {
446 type Output = Self;
447
448 #[inline]
452 fn rem(self, rhs: Self) -> Self {
453 Self(self.0.rem(rhs.0))
454 }
455}
456forward_ref_binop!(impl Rem, rem for Uint128, Uint128);
457
458impl RemAssign<Uint128> for Uint128 {
459 fn rem_assign(&mut self, rhs: Uint128) {
460 *self = *self % rhs;
461 }
462}
463forward_ref_op_assign!(impl RemAssign, rem_assign for Uint128, Uint128);
464
465impl ShrAssign<u32> for Uint128 {
466 fn shr_assign(&mut self, rhs: u32) {
467 *self = *self >> rhs;
468 }
469}
470
471impl<'a> ShrAssign<&'a u32> for Uint128 {
472 fn shr_assign(&mut self, rhs: &'a u32) {
473 *self = *self >> rhs;
474 }
475}
476
477impl Serialize for Uint128 {
478 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
480 where
481 S: ser::Serializer,
482 {
483 serializer.serialize_str(&self.to_string())
484 }
485}
486
487impl<'de> Deserialize<'de> for Uint128 {
488 fn deserialize<D>(deserializer: D) -> Result<Uint128, D::Error>
490 where
491 D: Deserializer<'de>,
492 {
493 deserializer.deserialize_str(Uint128Visitor)
494 }
495}
496
497struct Uint128Visitor;
498
499impl<'de> de::Visitor<'de> for Uint128Visitor {
500 type Value = Uint128;
501
502 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
503 formatter.write_str("string-encoded integer")
504 }
505
506 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
507 where
508 E: de::Error,
509 {
510 match v.parse::<u128>() {
511 Ok(u) => Ok(Uint128(u)),
512 Err(e) => Err(E::custom(format!("invalid Uint128 '{}' - {}", v, e))),
513 }
514 }
515}
516
517impl<A> std::iter::Sum<A> for Uint128
518where
519 Self: Add<A, Output = Self>,
520{
521 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
522 iter.fold(Self::zero(), Add::add)
523 }
524}
525
526impl PartialEq<&Uint128> for Uint128 {
527 fn eq(&self, rhs: &&Uint128) -> bool {
528 self == *rhs
529 }
530}
531
532impl PartialEq<Uint128> for &Uint128 {
533 fn eq(&self, rhs: &Uint128) -> bool {
534 *self == rhs
535 }
536}
537
538#[cfg(test)]
539mod tests {
540 use super::*;
541 use crate::{from_slice, to_vec};
542
543 #[test]
544 fn uint128_zero_works() {
545 let zero = Uint128::zero();
546 assert_eq!(
547 zero.to_be_bytes(),
548 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
549 );
550 }
551
552 #[test]
553 fn uint128_one_works() {
554 let one = Uint128::one();
555 assert_eq!(
556 one.to_be_bytes(),
557 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
558 );
559 }
560
561 #[test]
562 fn uint128_convert_into() {
563 let original = Uint128(12345);
564 let a = u128::from(original);
565 assert_eq!(a, 12345);
566
567 let original = Uint128(12345);
568 let a = String::from(original);
569 assert_eq!(a, "12345");
570 }
571
572 #[test]
573 fn uint128_convert_from() {
574 let a = Uint128::from(5u128);
575 assert_eq!(a.0, 5);
576
577 let a = Uint128::from(5u64);
578 assert_eq!(a.0, 5);
579
580 let a = Uint128::from(5u32);
581 assert_eq!(a.0, 5);
582
583 let a = Uint128::from(5u16);
584 assert_eq!(a.0, 5);
585
586 let a = Uint128::from(5u8);
587 assert_eq!(a.0, 5);
588
589 let result = Uint128::try_from("34567");
590 assert_eq!(result.unwrap().0, 34567);
591
592 let result = Uint128::try_from("1.23");
593 assert!(result.is_err());
594 }
595
596 #[test]
597 fn uint128_implements_display() {
598 let a = Uint128(12345);
599 assert_eq!(format!("Embedded: {}", a), "Embedded: 12345");
600 assert_eq!(a.to_string(), "12345");
601
602 let a = Uint128(0);
603 assert_eq!(format!("Embedded: {}", a), "Embedded: 0");
604 assert_eq!(a.to_string(), "0");
605 }
606
607 #[test]
608 fn uint128_display_padding_works() {
609 let a = Uint128::from(123u64);
610 assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123");
611 }
612
613 #[test]
614 fn uint128_to_be_bytes_works() {
615 assert_eq!(
616 Uint128::zero().to_be_bytes(),
617 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
618 );
619 assert_eq!(
620 Uint128::MAX.to_be_bytes(),
621 [
622 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
623 0xff, 0xff
624 ]
625 );
626 assert_eq!(
627 Uint128::new(1).to_be_bytes(),
628 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
629 );
630 assert_eq!(
632 Uint128::new(240282366920938463463374607431768124608).to_be_bytes(),
633 [180, 196, 179, 87, 165, 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192]
634 );
635 }
636
637 #[test]
638 fn uint128_to_le_bytes_works() {
639 assert_eq!(
640 Uint128::zero().to_le_bytes(),
641 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
642 );
643 assert_eq!(
644 Uint128::MAX.to_le_bytes(),
645 [
646 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
647 0xff, 0xff
648 ]
649 );
650 assert_eq!(
651 Uint128::new(1).to_le_bytes(),
652 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
653 );
654 assert_eq!(
656 Uint128::new(240282366920938463463374607431768124608).to_le_bytes(),
657 [192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180]
658 );
659 }
660
661 #[test]
662 fn uint128_is_zero_works() {
663 assert!(Uint128::zero().is_zero());
664 assert!(Uint128(0).is_zero());
665
666 assert!(!Uint128(1).is_zero());
667 assert!(!Uint128(123).is_zero());
668 }
669
670 #[test]
671 fn uint128_json() {
672 let orig = Uint128(1234567890987654321);
673 let serialized = to_vec(&orig).unwrap();
674 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
675 let parsed: Uint128 = from_slice(&serialized).unwrap();
676 assert_eq!(parsed, orig);
677 }
678
679 #[test]
680 fn uint128_compare() {
681 let a = Uint128(12345);
682 let b = Uint128(23456);
683
684 assert!(a < b);
685 assert!(b > a);
686 assert_eq!(a, Uint128(12345));
687 }
688
689 #[test]
690 #[allow(clippy::op_ref)]
691 fn uint128_math() {
692 let a = Uint128(12345);
693 let b = Uint128(23456);
694
695 assert_eq!(a + b, Uint128(35801));
697 assert_eq!(a + &b, Uint128(35801));
698
699 assert_eq!(b - a, Uint128(11111));
701 assert_eq!(b - &a, Uint128(11111));
702
703 let mut c = Uint128(300000);
705 c += b;
706 assert_eq!(c, Uint128(323456));
707 let mut d = Uint128(300000);
708 d += &b;
709 assert_eq!(d, Uint128(323456));
710
711 let mut c = Uint128(300000);
713 c -= b;
714 assert_eq!(c, Uint128(276544));
715 let mut d = Uint128(300000);
716 d -= &b;
717 assert_eq!(d, Uint128(276544));
718
719 let underflow_result = a.checked_sub(b);
721 let OverflowError {
722 operand1, operand2, ..
723 } = underflow_result.unwrap_err();
724 assert_eq!((operand1, operand2), (a.to_string(), b.to_string()));
725 }
726
727 #[test]
728 #[should_panic]
729 fn uint128_add_overflow_panics() {
730 let almost_max = Uint128(340282366920938463463374607431768211446);
732 let _ = almost_max + Uint128(12);
733 }
734
735 #[test]
736 #[allow(clippy::op_ref)]
737 fn uint128_sub_works() {
738 assert_eq!(Uint128(2) - Uint128(1), Uint128(1));
739 assert_eq!(Uint128(2) - Uint128(0), Uint128(2));
740 assert_eq!(Uint128(2) - Uint128(2), Uint128(0));
741
742 let a = Uint128::new(10);
744 let b = Uint128::new(3);
745 let expected = Uint128::new(7);
746 assert_eq!(a - b, expected);
747 assert_eq!(a - &b, expected);
748 assert_eq!(&a - b, expected);
749 assert_eq!(&a - &b, expected);
750 }
751
752 #[test]
753 #[should_panic]
754 fn uint128_sub_overflow_panics() {
755 let _ = Uint128(1) - Uint128(2);
756 }
757
758 #[test]
759 fn uint128_sub_assign_works() {
760 let mut a = Uint128(14);
761 a -= Uint128(2);
762 assert_eq!(a, Uint128(12));
763
764 let mut a = Uint128::new(10);
766 let b = Uint128::new(3);
767 let expected = Uint128::new(7);
768 a -= &b;
769 assert_eq!(a, expected);
770 }
771
772 #[test]
773 #[allow(clippy::op_ref)]
774 fn uint128_mul_works() {
775 assert_eq!(
776 Uint128::from(2u32) * Uint128::from(3u32),
777 Uint128::from(6u32)
778 );
779 assert_eq!(Uint128::from(2u32) * Uint128::zero(), Uint128::zero());
780
781 let a = Uint128::from(11u32);
783 let b = Uint128::from(3u32);
784 let expected = Uint128::from(33u32);
785 assert_eq!(a * b, expected);
786 assert_eq!(a * &b, expected);
787 assert_eq!(&a * b, expected);
788 assert_eq!(&a * &b, expected);
789 }
790
791 #[test]
792 fn uint128_mul_assign_works() {
793 let mut a = Uint128::from(14u32);
794 a *= Uint128::from(2u32);
795 assert_eq!(a, Uint128::from(28u32));
796
797 let mut a = Uint128::from(10u32);
799 let b = Uint128::from(3u32);
800 a *= &b;
801 assert_eq!(a, Uint128::from(30u32));
802 }
803
804 #[test]
805 fn uint128_pow_works() {
806 assert_eq!(Uint128::from(2u32).pow(2), Uint128::from(4u32));
807 assert_eq!(Uint128::from(2u32).pow(10), Uint128::from(1024u32));
808 }
809
810 #[test]
811 #[should_panic]
812 fn uint128_pow_overflow_panics() {
813 Uint128::MAX.pow(2u32);
814 }
815
816 #[test]
817 fn uint128_multiply_ratio_works() {
818 let base = Uint128(500);
819
820 assert_eq!(base.multiply_ratio(1u128, 1u128), base);
822 assert_eq!(base.multiply_ratio(3u128, 3u128), base);
823 assert_eq!(base.multiply_ratio(654321u128, 654321u128), base);
824 assert_eq!(base.multiply_ratio(u128::MAX, u128::MAX), base);
825
826 assert_eq!(base.multiply_ratio(3u128, 2u128), Uint128(750));
828 assert_eq!(base.multiply_ratio(333333u128, 222222u128), Uint128(750));
829
830 assert_eq!(base.multiply_ratio(2u128, 3u128), Uint128(333));
832 assert_eq!(base.multiply_ratio(222222u128, 333333u128), Uint128(333));
833
834 assert_eq!(base.multiply_ratio(5u128, 6u128), Uint128(416));
836 assert_eq!(base.multiply_ratio(100u128, 120u128), Uint128(416));
837 }
838
839 #[test]
840 fn uint128_multiply_ratio_does_not_overflow_when_result_fits() {
841 let base = Uint128(u128::MAX - 9);
843
844 assert_eq!(base.multiply_ratio(2u128, 2u128), base);
845 }
846
847 #[test]
848 #[should_panic]
849 fn uint128_multiply_ratio_panicks_on_overflow() {
850 let base = Uint128(u128::MAX - 9);
852
853 assert_eq!(base.multiply_ratio(2u128, 1u128), base);
854 }
855
856 #[test]
857 #[should_panic(expected = "Denominator must not be zero")]
858 fn uint128_multiply_ratio_panics_for_zero_denominator() {
859 Uint128(500).multiply_ratio(1u128, 0u128);
860 }
861
862 #[test]
863 fn uint128_checked_multiply_ratio_does_not_panic() {
864 assert_eq!(
865 Uint128(500u128).checked_multiply_ratio(1u128, 0u128),
866 Err(CheckedMultiplyRatioError::DivideByZero),
867 );
868 assert_eq!(
869 Uint128(500u128).checked_multiply_ratio(u128::MAX, 1u128),
870 Err(CheckedMultiplyRatioError::Overflow),
871 );
872 }
873
874 #[test]
875 fn sum_works() {
876 let nums = vec![Uint128(17), Uint128(123), Uint128(540), Uint128(82)];
877 let expected = Uint128(762);
878
879 let sum_as_ref: Uint128 = nums.iter().sum();
880 assert_eq!(expected, sum_as_ref);
881
882 let sum_as_owned: Uint128 = nums.into_iter().sum();
883 assert_eq!(expected, sum_as_owned);
884 }
885
886 #[test]
887 fn uint128_methods() {
888 assert!(matches!(
890 Uint128::MAX.checked_add(Uint128(1)),
891 Err(OverflowError { .. })
892 ));
893 assert!(matches!(Uint128(1).checked_add(Uint128(1)), Ok(Uint128(2))));
894 assert!(matches!(
895 Uint128(0).checked_sub(Uint128(1)),
896 Err(OverflowError { .. })
897 ));
898 assert!(matches!(Uint128(2).checked_sub(Uint128(1)), Ok(Uint128(1))));
899 assert!(matches!(
900 Uint128::MAX.checked_mul(Uint128(2)),
901 Err(OverflowError { .. })
902 ));
903 assert!(matches!(Uint128(2).checked_mul(Uint128(2)), Ok(Uint128(4))));
904 assert!(matches!(
905 Uint128::MAX.checked_pow(2u32),
906 Err(OverflowError { .. })
907 ));
908 assert!(matches!(Uint128(2).checked_pow(3), Ok(Uint128(8))));
909 assert!(matches!(
910 Uint128::MAX.checked_div(Uint128(0)),
911 Err(DivideByZeroError { .. })
912 ));
913 assert!(matches!(Uint128(6).checked_div(Uint128(2)), Ok(Uint128(3))));
914 assert!(matches!(
915 Uint128::MAX.checked_div_euclid(Uint128(0)),
916 Err(DivideByZeroError { .. })
917 ));
918 assert!(matches!(
919 Uint128(6).checked_div_euclid(Uint128(2)),
920 Ok(Uint128(3)),
921 ));
922 assert!(matches!(
923 Uint128::MAX.checked_rem(Uint128(0)),
924 Err(DivideByZeroError { .. })
925 ));
926
927 assert_eq!(Uint128::MAX.saturating_add(Uint128(1)), Uint128::MAX);
929 assert_eq!(Uint128(0).saturating_sub(Uint128(1)), Uint128(0));
930 assert_eq!(Uint128::MAX.saturating_mul(Uint128(2)), Uint128::MAX);
931 assert_eq!(Uint128::MAX.saturating_pow(2), Uint128::MAX);
932 }
933
934 #[test]
935 fn uint128_wrapping_methods() {
936 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!(
947 Uint128::MAX.wrapping_mul(Uint128(2)),
948 Uint128::MAX - Uint128::one()
949 ); assert_eq!(Uint128(2).wrapping_pow(3), Uint128(8)); assert_eq!(Uint128::MAX.wrapping_pow(2), Uint128(1)); }
955
956 #[test]
957 #[allow(clippy::op_ref)]
958 fn uint128_implements_rem() {
959 let a = Uint128::new(10);
960 assert_eq!(a % Uint128::new(10), Uint128::zero());
961 assert_eq!(a % Uint128::new(2), Uint128::zero());
962 assert_eq!(a % Uint128::new(1), Uint128::zero());
963 assert_eq!(a % Uint128::new(3), Uint128::new(1));
964 assert_eq!(a % Uint128::new(4), Uint128::new(2));
965
966 let a = Uint128::new(10);
968 let b = Uint128::new(3);
969 let expected = Uint128::new(1);
970 assert_eq!(a % b, expected);
971 assert_eq!(a % &b, expected);
972 assert_eq!(&a % b, expected);
973 assert_eq!(&a % &b, expected);
974 }
975
976 #[test]
977 #[should_panic(expected = "divisor of zero")]
978 fn uint128_rem_panics_for_zero() {
979 let _ = Uint128::new(10) % Uint128::zero();
980 }
981
982 #[test]
983 #[allow(clippy::op_ref)]
984 fn uint128_rem_works() {
985 assert_eq!(
986 Uint128::from(12u32) % Uint128::from(10u32),
987 Uint128::from(2u32)
988 );
989 assert_eq!(Uint128::from(50u32) % Uint128::from(5u32), Uint128::zero());
990
991 let a = Uint128::from(42u32);
993 let b = Uint128::from(5u32);
994 let expected = Uint128::from(2u32);
995 assert_eq!(a % b, expected);
996 assert_eq!(a % &b, expected);
997 assert_eq!(&a % b, expected);
998 assert_eq!(&a % &b, expected);
999 }
1000
1001 #[test]
1002 fn uint128_rem_assign_works() {
1003 let mut a = Uint128::from(30u32);
1004 a %= Uint128::from(4u32);
1005 assert_eq!(a, Uint128::from(2u32));
1006
1007 let mut a = Uint128::from(25u32);
1009 let b = Uint128::from(6u32);
1010 a %= &b;
1011 assert_eq!(a, Uint128::from(1u32));
1012 }
1013
1014 #[test]
1015 fn uint128_abs_diff_works() {
1016 let a = Uint128::from(42u32);
1017 let b = Uint128::from(5u32);
1018 let expected = Uint128::from(37u32);
1019 assert_eq!(a.abs_diff(b), expected);
1020 assert_eq!(b.abs_diff(a), expected);
1021 }
1022
1023 #[test]
1024 fn uint128_partial_eq() {
1025 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1026 .into_iter()
1027 .map(|(lhs, rhs, expected)| (Uint128::new(lhs), Uint128::new(rhs), expected));
1028
1029 #[allow(clippy::op_ref)]
1030 for (lhs, rhs, expected) in test_cases {
1031 assert_eq!(lhs == rhs, expected);
1032 assert_eq!(&lhs == rhs, expected);
1033 assert_eq!(lhs == &rhs, expected);
1034 assert_eq!(&lhs == &rhs, expected);
1035 }
1036 }
1037}