Skip to content

Commit

Permalink
Merge pull request #1264 from CosmWasm/1155-add-decimal-const-constru…
Browse files Browse the repository at this point in the history
…ctors

`Decimal`/`Decimal256`: Add `new` and `raw` const constructors
  • Loading branch information
ueco-jb authored Apr 4, 2022
2 parents e83b57b + e08b5c5 commit 5ad8703
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 13 deletions.
19 changes: 12 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
32 changes: 28 additions & 4 deletions packages/std/src/math/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
25 changes: 25 additions & 0 deletions packages/std/src/math/decimal256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand Down
23 changes: 21 additions & 2 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand All @@ -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 = [
Expand Down Expand Up @@ -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!(
Expand Down

0 comments on commit 5ad8703

Please sign in to comment.