Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing conversions between primitive and wrapped integer types #2348

Merged
merged 3 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ and this project adheres to

## [Unreleased]

## Added

- cosmwasm-std: Implement `From<Uint64> for u{64,128}`,
`From<Uint128> for u128`, `From<Int64> for i{64,128}`, and
`From<Int128> for i128` ([#2268])

[#2268]: https://github.com/CosmWasm/cosmwasm/issues/2268

## Fixed

- cosmwasm-schema: The schema export now doesn't overwrite existing
Expand Down
28 changes: 28 additions & 0 deletions packages/std/src/math/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,34 @@ macro_rules! forward_try_from {
}
pub(crate) use forward_try_from;

/// Helper macro to implement `From` for a type that is just a wrapper around another type.
/// This can be used for all our integer conversions where `bnum` implements `From`.
macro_rules! wrapped_int_to_primitive {
($input: ty, $output: ty) => {
impl From<$input> for $output {
fn from(value: $input) -> Self {
// By convention all our Uint*/Int* types store the value in .0
value.0.into()
}
}
};
}
pub(crate) use wrapped_int_to_primitive;

/// Helper macro to implement `From` for a type that is just a wrapper around another type.
/// This can be used for all our integer conversions where `bnum` implements `From`.
macro_rules! primitive_to_wrapped_int {
($input: ty, $output: ty) => {
impl From<$input> for $output {
fn from(value: $input) -> Self {
// By convention all our Uint*/Int* types store the value in .0
Self(value.into())
}
}
};
}
pub(crate) use primitive_to_wrapped_int;

/// Helper macro to implement `TryFrom` for a conversion from a bigger signed int to a smaller one.
/// This is needed because `bnum` does not implement `TryFrom` for those conversions
/// because of limitations of const generics.
Expand Down
72 changes: 20 additions & 52 deletions packages/std/src/math/int128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use crate::{
__internal::forward_ref_partial_eq,
};

use super::conversion::{forward_try_from, try_from_int_to_int};
use super::conversion::{
forward_try_from, primitive_to_wrapped_int, try_from_int_to_int, wrapped_int_to_primitive,
};
use super::impl_int_serde;
use super::num_consts::NumConsts;

Expand Down Expand Up @@ -306,29 +308,10 @@ forward_try_from!(Uint256, Int128);
forward_try_from!(Uint512, Int128);

// uint to Int
impl From<u64> for Int128 {
fn from(val: u64) -> Self {
Int128(val.into())
}
}

impl From<u32> for Int128 {
fn from(val: u32) -> Self {
Int128(val.into())
}
}

impl From<u16> for Int128 {
fn from(val: u16) -> Self {
Int128(val.into())
}
}

impl From<u8> for Int128 {
fn from(val: u8) -> Self {
Int128(val.into())
}
}
primitive_to_wrapped_int!(u8, Int128);
primitive_to_wrapped_int!(u16, Int128);
primitive_to_wrapped_int!(u32, Int128);
primitive_to_wrapped_int!(u64, Int128);

// Int to Int
impl From<Int64> for Int128 {
Expand All @@ -341,35 +324,14 @@ try_from_int_to_int!(Int256, Int128);
try_from_int_to_int!(Int512, Int128);

// int to Int
impl From<i128> for Int128 {
fn from(val: i128) -> Self {
Int128(val)
}
}
primitive_to_wrapped_int!(i8, Int128);
primitive_to_wrapped_int!(i16, Int128);
primitive_to_wrapped_int!(i32, Int128);
primitive_to_wrapped_int!(i64, Int128);
primitive_to_wrapped_int!(i128, Int128);

impl From<i64> for Int128 {
fn from(val: i64) -> Self {
Int128(val.into())
}
}

impl From<i32> for Int128 {
fn from(val: i32) -> Self {
Int128(val.into())
}
}

impl From<i16> for Int128 {
fn from(val: i16) -> Self {
Int128(val.into())
}
}

impl From<i8> for Int128 {
fn from(val: i8) -> Self {
Int128(val.into())
}
}
// Int to int
wrapped_int_to_primitive!(Int128, i128);

impl TryFrom<&str> for Int128 {
type Error = StdError;
Expand Down Expand Up @@ -626,6 +588,12 @@ mod tests {
assert_eq!(num1, num2);
}

#[test]
fn int128_convert_to() {
let a = Int128::new(5);
assert_eq!(i128::from(a), 5);
}

#[test]
fn int128_convert_from() {
let a = Int128::from(5i128);
Expand Down
72 changes: 13 additions & 59 deletions packages/std/src/math/int256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::{
/// the implementation in the future.
use bnum::types::{I256, U256};

use super::conversion::{grow_be_int, try_from_int_to_int, try_from_uint_to_int};
use super::conversion::{
grow_be_int, primitive_to_wrapped_int, try_from_int_to_int, try_from_uint_to_int,
};
use super::impl_int_serde;
use super::num_consts::NumConsts;

Expand Down Expand Up @@ -370,35 +372,11 @@ impl From<Uint64> for Int256 {
}

// uint to Int
impl From<u128> for Int256 {
fn from(val: u128) -> Self {
Int256(val.into())
}
}

impl From<u64> for Int256 {
fn from(val: u64) -> Self {
Int256(val.into())
}
}

impl From<u32> for Int256 {
fn from(val: u32) -> Self {
Int256(val.into())
}
}

impl From<u16> for Int256 {
fn from(val: u16) -> Self {
Int256(val.into())
}
}

impl From<u8> for Int256 {
fn from(val: u8) -> Self {
Int256(val.into())
}
}
primitive_to_wrapped_int!(u8, Int256);
primitive_to_wrapped_int!(u16, Int256);
primitive_to_wrapped_int!(u32, Int256);
primitive_to_wrapped_int!(u64, Int256);
primitive_to_wrapped_int!(u128, Int256);

// Int to Int
try_from_int_to_int!(Int512, Int256);
Expand All @@ -416,35 +394,11 @@ impl From<Int64> for Int256 {
}

// int to Int
impl From<i128> for Int256 {
fn from(val: i128) -> Self {
Int256(val.into())
}
}

impl From<i64> for Int256 {
fn from(val: i64) -> Self {
Int256(val.into())
}
}

impl From<i32> for Int256 {
fn from(val: i32) -> Self {
Int256(val.into())
}
}

impl From<i16> for Int256 {
fn from(val: i16) -> Self {
Int256(val.into())
}
}

impl From<i8> for Int256 {
fn from(val: i8) -> Self {
Int256(val.into())
}
}
primitive_to_wrapped_int!(i8, Int256);
primitive_to_wrapped_int!(i16, Int256);
primitive_to_wrapped_int!(i32, Int256);
primitive_to_wrapped_int!(i64, Int256);
primitive_to_wrapped_int!(i128, Int256);

impl TryFrom<&str> for Int256 {
type Error = StdError;
Expand Down
70 changes: 11 additions & 59 deletions packages/std/src/math/int512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
/// the implementation in the future.
use bnum::types::{I512, U512};

use super::conversion::{grow_be_int, try_from_uint_to_int};
use super::conversion::{grow_be_int, primitive_to_wrapped_int, try_from_uint_to_int};
use super::impl_int_serde;
use super::num_consts::NumConsts;

Expand Down Expand Up @@ -365,66 +365,18 @@ impl From<Uint64> for Int512 {
}

// uint to Int
impl From<u128> for Int512 {
fn from(val: u128) -> Self {
Int512(val.into())
}
}

impl From<u64> for Int512 {
fn from(val: u64) -> Self {
Int512(val.into())
}
}

impl From<u32> for Int512 {
fn from(val: u32) -> Self {
Int512(val.into())
}
}

impl From<u16> for Int512 {
fn from(val: u16) -> Self {
Int512(val.into())
}
}

impl From<u8> for Int512 {
fn from(val: u8) -> Self {
Int512(val.into())
}
}
primitive_to_wrapped_int!(u8, Int512);
primitive_to_wrapped_int!(u16, Int512);
primitive_to_wrapped_int!(u32, Int512);
primitive_to_wrapped_int!(u64, Int512);
primitive_to_wrapped_int!(u128, Int512);

// int to Int
impl From<i128> for Int512 {
fn from(val: i128) -> Self {
Int512(val.into())
}
}

impl From<i64> for Int512 {
fn from(val: i64) -> Self {
Int512(val.into())
}
}

impl From<i32> for Int512 {
fn from(val: i32) -> Self {
Int512(val.into())
}
}

impl From<i16> for Int512 {
fn from(val: i16) -> Self {
Int512(val.into())
}
}

impl From<i8> for Int512 {
fn from(val: i8) -> Self {
Int512(val.into())
}
}
primitive_to_wrapped_int!(i8, Int512);
primitive_to_wrapped_int!(i16, Int512);
primitive_to_wrapped_int!(i32, Int512);
primitive_to_wrapped_int!(i64, Int512);
primitive_to_wrapped_int!(i128, Int512);

// Int to Int
impl From<Int64> for Int512 {
Expand Down
Loading
Loading