From 5edb2c012415a851d1b586bae005bffb5d34e635 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 8 Jun 2021 12:03:24 +0200 Subject: [PATCH] Implement Sub for Uint128 (closes #858) --- CHANGELOG.md | 4 +++ packages/std/src/math/uint128.rs | 47 ++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1e3d17f23..57806e4911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to ## [Unreleased] +### Added + +- cosmwasm-std: Implement `Sub` and `SubAssign` for `Uint128` + ### Removed - cosmwasm-std: Make `Uint128` inner field private ([#905]) diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 84cd1b7262..ab7ba7d1e5 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -206,6 +206,22 @@ impl<'a> ops::Add<&'a Uint128> for Uint128 { } } +impl ops::Sub for Uint128 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Uint128(self.u128().checked_sub(rhs.u128()).unwrap()) + } +} + +impl<'a> ops::Sub<&'a Uint128> for Uint128 { + type Output = Self; + + fn sub(self, rhs: &'a Uint128) -> Self { + Uint128(self.u128().checked_sub(rhs.u128()).unwrap()) + } +} + impl ops::AddAssign for Uint128 { fn add_assign(&mut self, rhs: Uint128) { self.0 = self.0.checked_add(rhs.u128()).unwrap(); @@ -218,6 +234,18 @@ impl<'a> ops::AddAssign<&'a Uint128> for Uint128 { } } +impl ops::SubAssign for Uint128 { + fn sub_assign(&mut self, rhs: Uint128) { + self.0 = self.0.checked_sub(rhs.u128()).unwrap(); + } +} + +impl<'a> ops::SubAssign<&'a Uint128> for Uint128 { + fn sub_assign(&mut self, rhs: &'a Uint128) { + self.0 = self.0.checked_sub(rhs.u128()).unwrap(); + } +} + impl Uint128 { /// Returns `self * numerator / denominator` pub fn multiply_ratio, B: Into>( @@ -397,7 +425,8 @@ mod tests { assert_eq!(a + &b, Uint128(35801)); // test - with owned and reference right hand side - assert_eq!((b.checked_sub(a)).unwrap(), Uint128(11111)); + assert_eq!(b - a, Uint128(11111)); + assert_eq!(b - &a, Uint128(11111)); // test += with owned and reference right hand side let mut c = Uint128(300000); @@ -407,6 +436,14 @@ mod tests { d += &b; assert_eq!(d, Uint128(323456)); + // test -= with owned and reference right hand side + let mut c = Uint128(300000); + c -= b; + assert_eq!(c, Uint128(276544)); + let mut d = Uint128(300000); + d -= &b; + assert_eq!(d, Uint128(276544)); + // error result on underflow (- would produce negative result) let underflow_result = a.checked_sub(b); let OverflowError { @@ -417,12 +454,18 @@ mod tests { #[test] #[should_panic] - fn uint128_math_overflow_panics() { + fn uint128_add_overflow_panics() { // almost_max is 2^128 - 10 let almost_max = Uint128(340282366920938463463374607431768211446); let _ = almost_max + Uint128(12); } + #[test] + #[should_panic] + fn uint128_sub_overflow_panics() { + let _ = Uint128(1) - Uint128(2); + } + #[test] fn uint128_multiply_ratio_works() { let base = Uint128(500);