diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ac32424eb..6b20f92a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,21 @@ and this project adheres to ## [Unreleased] +### Added + +- cosmwasm-std: Implement `MulAssign` for `Decimal`/`Decimal256`. +- cosmwasm-std: Implement `is_zero`/`atomics`/`decimal_places` as const for Uint + and Decimal types. +- cosmwasm-std: Implement `new` and `raw` const constructors for + `Decimal`/`Decimal256`. + ### Changed - all: Drop support for Rust versions lower than 1.56.1. +- cosmwasm-std: `MockQuerier` now supports adding custom behaviour for handling + Wasm queries via `MockQuerier::update_wasm` ([#1050]). + +[#1050]: https://github.com/CosmWasm/cosmwasm/pull/1050 ## [1.0.0-beta7] - 2022-03-22 @@ -22,18 +34,11 @@ 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-std: Implement `is_zero`/`atomics`/`decimal_places` as const for Uint - and Decimal types. - cosmwasm-crypto: Upgrade ed25519-zebra to version 3. ### Changed - cosmwasm-vm: Upgrade Wasmer to 2.2.1. -- cosmwasm-std: `MockQuerier` now supports adding custom behaviour for handling - Wasm queries via `MockQuerier::update_wasm` ([#1050]). - -[#1050]: https://github.com/CosmWasm/cosmwasm/pull/1050 ## [1.0.0-beta6] - 2022-03-07 diff --git a/packages/std/src/math/decimal.rs b/packages/std/src/math/decimal.rs index d5522db999..c71792e371 100644 --- a/packages/std/src/math/decimal.rs +++ b/packages/std/src/math/decimal.rs @@ -33,24 +33,36 @@ impl Decimal { pub const MAX: Self = Self(Uint128::MAX); + /// Creates a Decimal(value) + /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context. + pub const fn new(value: Uint128) -> Self { + Self(value) + } + + /// Creates a Decimal(Uint128(value)) + /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context. + pub const fn raw(value: u128) -> Self { + Self(Uint128::new(value)) + } + /// Create a 1.0 Decimal pub const fn one() -> Self { - Decimal(Self::DECIMAL_FRACTIONAL) + Self(Self::DECIMAL_FRACTIONAL) } /// Create a 0.0 Decimal pub const fn zero() -> Self { - Decimal(Uint128::zero()) + Self(Uint128::zero()) } /// Convert x% into Decimal pub fn percent(x: u64) -> Self { - Decimal(((x as u128) * 10_000_000_000_000_000).into()) + Self(((x as u128) * 10_000_000_000_000_000).into()) } /// Convert permille (x/1000) into Decimal pub fn permille(x: u64) -> Self { - Decimal(((x as u128) * 1_000_000_000_000_000).into()) + Self(((x as u128) * 1_000_000_000_000_000).into()) } /// Creates a decimal from a number of atomic units and the number @@ -478,6 +490,18 @@ mod tests { use super::*; use crate::{from_slice, to_vec}; + #[test] + fn decimal_new() { + let expected = Uint128::from(300u128); + assert_eq!(Decimal::new(expected).0, expected); + } + + #[test] + fn decimal_raw() { + let value = 300u128; + assert_eq!(Decimal::raw(value).0.u128(), value); + } + #[test] fn decimal_one() { let value = Decimal::one(); diff --git a/packages/std/src/math/decimal256.rs b/packages/std/src/math/decimal256.rs index a71d29fdd8..fe55ce71d6 100644 --- a/packages/std/src/math/decimal256.rs +++ b/packages/std/src/math/decimal256.rs @@ -42,6 +42,18 @@ impl Decimal256 { pub const MAX: Self = Self(Uint256::MAX); + /// Creates a Decimal256 from Uint256 + /// This is equivalent to `Decimal256::from_atomics(value, 18)` but usable in a const context. + pub const fn new(value: Uint256) -> Self { + Self(value) + } + + /// Creates a Decimal256 from u128 + /// This is equivalent to `Decimal256::from_atomics(value, 18)` but usable in a const context. + pub const fn raw(value: u128) -> Self { + Self(Uint256::from_u128(value)) + } + /// Create a 1.0 Decimal256 pub const fn one() -> Self { Self(Self::DECIMAL_FRACTIONAL) @@ -491,6 +503,19 @@ mod tests { use crate::errors::StdError; use crate::{from_slice, to_vec}; + #[test] + fn decimal256_new() { + let expected = Uint256::from(300u128); + assert_eq!(Decimal256::new(expected).0, expected); + } + + #[test] + fn decimal256_raw() { + let value = 300u128; + let expected = Uint256::from(value); + assert_eq!(Decimal256::raw(value).0, expected); + } + #[test] fn decimal256_one() { let value = Decimal256::one(); diff --git a/packages/std/src/math/uint256.rs b/packages/std/src/math/uint256.rs index 5eb8e48e4f..2df305cdec 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -102,9 +102,9 @@ impl Uint256 { Uint256(U256(words)) } - /// A conversion from `Uint128` that, unlike the one provided by the `From` trait, + /// A conversion from `u128` that, unlike the one provided by the `From` trait, /// can be used in a `const` context. - pub const fn from_uint128(num: Uint128) -> Self { + pub const fn from_u128(num: u128) -> Self { let bytes = num.to_le_bytes(); Self::from_le_bytes([ @@ -114,6 +114,12 @@ impl Uint256 { ]) } + /// A conversion from `Uint128` that, unlike the one provided by the `From` trait, + /// can be used in a `const` context. + pub const fn from_uint128(num: Uint128) -> Self { + Self::from_u128(num.u128()) + } + /// Returns a copy of the number as big endian bytes. pub const fn to_be_bytes(self) -> [u8; 32] { let words = [ @@ -945,6 +951,19 @@ mod tests { ); } + #[test] + fn uint256_from_u128() { + assert_eq!( + Uint256::from_u128(123u128), + Uint256::from_str("123").unwrap() + ); + + assert_eq!( + Uint256::from_u128(9785746283745u128), + Uint256::from_str("9785746283745").unwrap() + ); + } + #[test] fn uint256_from_uint128() { assert_eq!(