From 1dc8a3c9482b3a5c8bc4ec088aebb277e8d08791 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki Date: Tue, 29 Mar 2022 11:17:19 +0200 Subject: [PATCH] Implement MulAssign and mul for refs for Decimal/Decimal256 types --- CHANGELOG.md | 1 + packages/std/src/math/decimal.rs | 33 ++++++++++++++++++++++++++++- packages/std/src/math/decimal256.rs | 33 ++++++++++++++++++++++++++++- packages/std/src/math/mod.rs | 6 +++--- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2545851449..c8e4be7f25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to `Uint64`/`Uint128`/`Uint256`/`Uint512`. - cosmwasm-std: Implement `pow`/`checked_pow` for `Uint64`/`Uint128`/`Uint512`. - cosmwasm-std: Implement `SubAssign`/`AddAssign` for `Decimal`/`Decimal256`. +- cosmwasm-std: Implement `MulAssign` for `Decimal`/`Decimal256`. - cosmwasm-crypto: Upgrade ed25519-zebra to version 3. ### Changed diff --git a/packages/std/src/math/decimal.rs b/packages/std/src/math/decimal.rs index f710f799fe..c7d78c97eb 100644 --- a/packages/std/src/math/decimal.rs +++ b/packages/std/src/math/decimal.rs @@ -4,7 +4,7 @@ use serde::{de, ser, Deserialize, Deserializer, Serialize}; use std::cmp::Ordering; use std::convert::TryInto; use std::fmt::{self, Write}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, Sub, SubAssign}; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use std::str::FromStr; use thiserror::Error; @@ -377,6 +377,14 @@ impl Mul for Decimal { } } } +forward_ref_binop!(impl Mul, mul for Decimal, Decimal); + +impl MulAssign for Decimal { + fn mul_assign(&mut self, rhs: Decimal) { + *self = *self * rhs; + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal); /// Both d*u and u*d with d: Decimal and u: Uint128 returns an Uint128. There is no /// specific reason for this decision other than the initial use cases we have. If you @@ -958,6 +966,7 @@ mod tests { } #[test] + #[allow(clippy::op_ref)] fn decimal_implements_mul() { let one = Decimal::one(); let two = one + one; @@ -1064,6 +1073,28 @@ mod tests { max * dec("0.000000000000000001"), dec("340.282366920938463463") ); + + // works for refs + let a = Decimal::percent(20); + let b = Decimal::percent(30); + let expected = Decimal::percent(6); + assert_eq!(a * b, expected); + assert_eq!(&a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn decimal_mul_assign_works() { + let mut a = Decimal::percent(15); + a *= Decimal::percent(60); + assert_eq!(a, Decimal::percent(9)); + + // works for refs + let mut a = Decimal::percent(50); + let b = Decimal::percent(20); + a *= &b; + assert_eq!(a, Decimal::percent(10)); } #[test] diff --git a/packages/std/src/math/decimal256.rs b/packages/std/src/math/decimal256.rs index 02296aebd9..98c5059214 100644 --- a/packages/std/src/math/decimal256.rs +++ b/packages/std/src/math/decimal256.rs @@ -4,7 +4,7 @@ use serde::{de, ser, Deserialize, Deserializer, Serialize}; use std::cmp::Ordering; use std::convert::TryInto; use std::fmt::{self, Write}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, Sub, SubAssign}; +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use std::str::FromStr; use thiserror::Error; @@ -389,6 +389,14 @@ impl Mul for Decimal256 { } } } +forward_ref_binop!(impl Mul, mul for Decimal256, Decimal256); + +impl MulAssign for Decimal256 { + fn mul_assign(&mut self, rhs: Self) { + *self = *self * rhs; + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal256, Decimal256); /// Both d*u and u*d with d: Decimal256 and u: Uint256 returns an Uint256. There is no /// specific reason for this decision other than the initial use cases we have. If you @@ -1045,6 +1053,7 @@ mod tests { } #[test] + #[allow(clippy::op_ref)] fn decimal256_implements_mul() { let one = Decimal256::one(); let two = one + one; @@ -1151,6 +1160,28 @@ mod tests { max * dec("0.000000000000000001"), dec("115792089237316195423570985008687907853269.984665640564039457") ); + + // works for refs + let a = Decimal256::percent(20); + let b = Decimal256::percent(30); + let expected = Decimal256::percent(6); + assert_eq!(a * b, expected); + assert_eq!(&a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn decimal256_mul_assign_works() { + let mut a = Decimal256::percent(15); + a *= Decimal256::percent(60); + assert_eq!(a, Decimal256::percent(9)); + + // works for refs + let mut a = Decimal256::percent(50); + let b = Decimal256::percent(20); + a *= &b; + assert_eq!(a, Decimal256::percent(10)); } #[test] diff --git a/packages/std/src/math/mod.rs b/packages/std/src/math/mod.rs index 747d21704f..2190d0dccc 100644 --- a/packages/std/src/math/mod.rs +++ b/packages/std/src/math/mod.rs @@ -67,9 +67,9 @@ mod tests { + SubAssign + SubAssign<&'a Self> + Mul - // + Mul<&'a Self> - // + MulAssign - // + MulAssign<&'a Self> + + Mul<&'a Self> + + MulAssign + + MulAssign<&'a Self> // + Div // + Div<&'a Self> // + DivAssign