diff --git a/CHANGELOG.md b/CHANGELOG.md index cadd35424..85ac0e235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,34 @@ and this project adheres to ## [Unreleased] +# <<<<<<< HEAD + +## Added + +- cosmwasm-std: Implement `From for u{64,128}`, + `From for u128`, `From for i{64,128}`, and + `From for i128` ([#2268]) +- cosmwasm-std: Deprecate `abort` feature. The panic handler is now always + enabled. ([#2337]) +- cosmwasm-std: Implement `Uint128::from_{be,le}_bytes` and + `Uint64::from_{be,le}_bytes`. ([#2269]) + +[#2268]: https://github.com/CosmWasm/cosmwasm/issues/2268 +[#2337]: https://github.com/CosmWasm/cosmwasm/issues/2337 +[#2269]: https://github.com/CosmWasm/cosmwasm/issues/2269 + +## Fixed + +- cosmwasm-schema: The schema export now doesn't overwrite existing + `additionalProperties` values anymore ([#2310]) +- cosmwasm-std: Added new `EurekaMsg` and `CosmosMsg::Eureka` variant ([#2340]) + +[#2310]: https://github.com/CosmWasm/cosmwasm/pull/2310 +[#2340]: https://github.com/CosmWasm/cosmwasm/pull/2340 + +> > > > > > > 23de2fcd (Implement from_be_bytes/from_le_bytes for Uint64 and +> > > > > > > Uint128) + ## [2.2.0] - 2024-12-17 ### Added diff --git a/packages/std/src/math/conversion.rs b/packages/std/src/math/conversion.rs index 8b31b8461..5da5b4e46 100644 --- a/packages/std/src/math/conversion.rs +++ b/packages/std/src/math/conversion.rs @@ -298,6 +298,35 @@ macro_rules! try_from_int_to_uint { } pub(crate) use try_from_int_to_uint; +macro_rules! from_and_to_bytes { + ($inner: ty, $byte_size: literal) => { + /// Constructs new value from big endian bytes + #[must_use] + pub const fn from_be_bytes(data: [u8; $byte_size]) -> Self { + Self(<$inner>::from_be_bytes(data)) + } + + /// Constructs new value from little endian bytes + #[must_use] + pub const fn from_le_bytes(data: [u8; $byte_size]) -> Self { + Self(<$inner>::from_le_bytes(data)) + } + + /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_be_bytes(self) -> [u8; $byte_size] { + self.0.to_be_bytes() + } + + /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_le_bytes(self) -> [u8; $byte_size] { + self.0.to_le_bytes() + } + }; +} +pub(crate) use from_and_to_bytes; + #[cfg(test)] mod tests { use super::*; diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs index 9f0f35d59..fe5c4cf2b 100644 --- a/packages/std/src/math/int128.rs +++ b/packages/std/src/math/int128.rs @@ -13,7 +13,14 @@ use crate::{ __internal::forward_ref_partial_eq, }; +<<<<<<< HEAD use super::conversion::{forward_try_from, try_from_int_to_int}; +======= +use super::conversion::{ + forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, try_from_int_to_int, + wrapped_int_to_primitive, +}; +>>>>>>> 73dd0892 (Create and use from_and_to_bytes) use super::impl_int_serde; use super::num_consts::NumConsts; @@ -65,27 +72,7 @@ impl Int128 { self.0 } - #[must_use] - pub const fn from_be_bytes(data: [u8; 16]) -> Self { - Self(i128::from_be_bytes(data)) - } - - #[must_use] - pub const fn from_le_bytes(data: [u8; 16]) -> Self { - Self(i128::from_le_bytes(data)) - } - - /// Returns a copy of the number as big endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_be_bytes(self) -> [u8; 16] { - self.0.to_be_bytes() - } - - /// Returns a copy of the number as little endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_le_bytes(self) -> [u8; 16] { - self.0.to_le_bytes() - } + from_and_to_bytes!(i128, 16); #[must_use] pub const fn is_zero(&self) -> bool { @@ -559,16 +546,64 @@ mod tests { #[test] fn int128_from_be_bytes_works() { - let num = Int128::from_be_bytes([1; 16]); + // zero + let original = [0; 16]; + let num = Int128::from_be_bytes(original); + assert!(num.is_zero()); + + // one + let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; + let num = Int128::from_be_bytes(original); + assert_eq!(num.i128(), 1); + + // 258 + let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]; + let num = Int128::from_be_bytes(original); + assert_eq!(num.i128(), 258); + + // 2x roundtrip + let original = [1; 16]; + let num = Int128::from_be_bytes(original); let a: [u8; 16] = num.to_be_bytes(); - assert_eq!(a, [1; 16]); + assert_eq!(a, original); - let be_bytes = [ + let original = [ 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, ]; - let num = Int128::from_be_bytes(be_bytes); + let num = Int128::from_be_bytes(original); let resulting_bytes: [u8; 16] = num.to_be_bytes(); - assert_eq!(be_bytes, resulting_bytes); + assert_eq!(resulting_bytes, original); + } + + #[test] + fn int128_from_le_bytes_works() { + // zero + let original = [0; 16]; + let num = Int128::from_le_bytes(original); + assert!(num.is_zero()); + + // one + let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let num = Int128::from_le_bytes(original); + assert_eq!(num.i128(), 1); + + // 258 + let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let num = Int128::from_le_bytes(original); + assert_eq!(num.i128(), 258); + + // 2x roundtrip + let original = [1; 16]; + let num = Int128::from_le_bytes(original); + let a: [u8; 16] = num.to_le_bytes(); + assert_eq!(a, original); + + let original = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Int128::from_le_bytes(original); + let resulting_bytes: [u8; 16] = num.to_le_bytes(); + assert_eq!(resulting_bytes, original); } #[test] diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs index 3a3594fe4..af2cbe57c 100644 --- a/packages/std/src/math/int64.rs +++ b/packages/std/src/math/int64.rs @@ -13,7 +13,14 @@ use crate::{ __internal::forward_ref_partial_eq, }; +<<<<<<< HEAD use super::conversion::{forward_try_from, try_from_int_to_int}; +======= +use super::conversion::{ + forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, try_from_int_to_int, + wrapped_int_to_primitive, +}; +>>>>>>> 73dd0892 (Create and use from_and_to_bytes) use super::impl_int_serde; use super::num_consts::NumConsts; @@ -65,27 +72,7 @@ impl Int64 { self.0 } - #[must_use] - pub const fn from_be_bytes(data: [u8; 8]) -> Self { - Self(i64::from_be_bytes(data)) - } - - #[must_use] - pub const fn from_le_bytes(data: [u8; 8]) -> Self { - Self(i64::from_le_bytes(data)) - } - - /// Returns a copy of the number as big endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_be_bytes(self) -> [u8; 8] { - self.0.to_be_bytes() - } - - /// Returns a copy of the number as little endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_le_bytes(self) -> [u8; 8] { - self.0.to_le_bytes() - } + from_and_to_bytes!(i64, 8); #[must_use] pub const fn is_zero(&self) -> bool { @@ -538,14 +525,60 @@ mod tests { #[test] fn int64_from_be_bytes_works() { - let num = Int64::from_be_bytes([1; 8]); + // zero + let original = [0; 8]; + let num = Int64::from_be_bytes(original); + assert!(num.is_zero()); + + // one + let original = [0, 0, 0, 0, 0, 0, 0, 1]; + let num = Int64::from_be_bytes(original); + assert_eq!(num.i64(), 1); + + // 258 + let original = [0, 0, 0, 0, 0, 0, 1, 2]; + let num = Int64::from_be_bytes(original); + assert_eq!(num.i64(), 258); + + // 2x roundtrip + let original = [1; 8]; + let num = Int64::from_be_bytes(original); let a: [u8; 8] = num.to_be_bytes(); - assert_eq!(a, [1; 8]); + assert_eq!(a, original); - let be_bytes = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; - let num = Int64::from_be_bytes(be_bytes); - let resulting_bytes: [u8; 8] = num.to_be_bytes(); - assert_eq!(be_bytes, resulting_bytes); + let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let num = Int64::from_be_bytes(original); + let a: [u8; 8] = num.to_be_bytes(); + assert_eq!(a, original); + } + + #[test] + fn int64_from_le_bytes_works() { + // zero + let original = [0; 8]; + let num = Int64::from_le_bytes(original); + assert!(num.is_zero()); + + // one + let original = [1, 0, 0, 0, 0, 0, 0, 0]; + let num = Int64::from_le_bytes(original); + assert_eq!(num.i64(), 1); + + // 258 + let original = [2, 1, 0, 0, 0, 0, 0, 0]; + let num = Int64::from_le_bytes(original); + assert_eq!(num.i64(), 258); + + // 2x roundtrip + let original = [1; 8]; + let num = Int64::from_le_bytes(original); + let a: [u8; 8] = num.to_le_bytes(); + assert_eq!(a, original); + + let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let num = Int64::from_le_bytes(original); + let a: [u8; 8] = num.to_le_bytes(); + assert_eq!(a, original); } #[test] diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 1511deca7..6d2690f58 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -16,7 +16,13 @@ use crate::{ Uint256, Uint64, }; +<<<<<<< HEAD use super::conversion::forward_try_from; +======= +use super::conversion::{ + forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, wrapped_int_to_primitive, +}; +>>>>>>> 23de2fcd (Implement from_be_bytes/from_le_bytes for Uint64 and Uint128) use super::impl_int_serde; use super::num_consts::NumConsts; @@ -73,17 +79,7 @@ impl Uint128 { self.0 } - /// Returns a copy of the number as big endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_be_bytes(self) -> [u8; 16] { - self.0.to_be_bytes() - } - - /// Returns a copy of the number as little endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_le_bytes(self) -> [u8; 16] { - self.0.to_le_bytes() - } + from_and_to_bytes!(u128, 16); #[must_use] pub const fn is_zero(&self) -> bool { @@ -631,6 +627,68 @@ mod tests { ); } + #[test] + fn uint128_from_be_bytes_works() { + // zero + let original = [0; 16]; + let num = Uint128::from_be_bytes(original); + assert!(num.is_zero()); + + // one + let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; + let num = Uint128::from_be_bytes(original); + assert_eq!(num.u128(), 1); + + // 258 + let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]; + let num = Uint128::from_be_bytes(original); + assert_eq!(num.u128(), 258); + + // 2x roundtrip + let original = [1; 16]; + let num = Uint128::from_be_bytes(original); + let a: [u8; 16] = num.to_be_bytes(); + assert_eq!(a, original); + + let original = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Uint128::from_be_bytes(original); + let resulting_bytes: [u8; 16] = num.to_be_bytes(); + assert_eq!(resulting_bytes, original); + } + + #[test] + fn uint128_from_le_bytes_works() { + // zero + let original = [0; 16]; + let num = Uint128::from_le_bytes(original); + assert!(num.is_zero()); + + // one + let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let num = Uint128::from_le_bytes(original); + assert_eq!(num.u128(), 1); + + // 258 + let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let num = Uint128::from_le_bytes(original); + assert_eq!(num.u128(), 258); + + // 2x roundtrip + let original = [1; 16]; + let num = Uint128::from_le_bytes(original); + let a: [u8; 16] = num.to_le_bytes(); + assert_eq!(a, original); + + let original = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Uint128::from_le_bytes(original); + let resulting_bytes: [u8; 16] = num.to_le_bytes(); + assert_eq!(resulting_bytes, original); + } + #[test] fn uint128_convert_into() { let original = Uint128(12345); diff --git a/packages/std/src/math/uint64.rs b/packages/std/src/math/uint64.rs index 9fecc2495..e330ed51a 100644 --- a/packages/std/src/math/uint64.rs +++ b/packages/std/src/math/uint64.rs @@ -15,7 +15,13 @@ use crate::{ Uint128, }; +<<<<<<< HEAD use super::conversion::forward_try_from; +======= +use super::conversion::{ + forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, wrapped_int_to_primitive, +}; +>>>>>>> 23de2fcd (Implement from_be_bytes/from_le_bytes for Uint64 and Uint128) use super::impl_int_serde; use super::num_consts::NumConsts; @@ -69,17 +75,7 @@ impl Uint64 { self.0 } - /// Returns a copy of the number as big endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_be_bytes(self) -> [u8; 8] { - self.0.to_be_bytes() - } - - /// Returns a copy of the number as little endian bytes. - #[must_use = "this returns the result of the operation, without modifying the original"] - pub const fn to_le_bytes(self) -> [u8; 8] { - self.0.to_le_bytes() - } + from_and_to_bytes!(u64, 8); #[must_use] pub const fn is_zero(&self) -> bool { @@ -593,6 +589,64 @@ mod tests { assert_eq!(one.to_be_bytes(), [0, 0, 0, 0, 0, 0, 0, 1]); } + #[test] + fn uint64_from_be_bytes_works() { + // zero + let original = [0; 8]; + let num = Uint64::from_be_bytes(original); + assert!(num.is_zero()); + + // one + let original = [0, 0, 0, 0, 0, 0, 0, 1]; + let num = Uint64::from_be_bytes(original); + assert_eq!(num.u64(), 1); + + // 258 + let original = [0, 0, 0, 0, 0, 0, 1, 2]; + let num = Uint64::from_be_bytes(original); + assert_eq!(num.u64(), 258); + + // 2x roundtrip + let original = [1; 8]; + let num = Uint64::from_be_bytes(original); + let a: [u8; 8] = num.to_be_bytes(); + assert_eq!(a, original); + + let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let num = Uint64::from_be_bytes(original); + let resulting_bytes: [u8; 8] = num.to_be_bytes(); + assert_eq!(resulting_bytes, original); + } + + #[test] + fn uint64_from_le_bytes_works() { + // zero + let original = [0; 8]; + let num = Uint64::from_le_bytes(original); + assert!(num.is_zero()); + + // one + let original = [1, 0, 0, 0, 0, 0, 0, 0]; + let num = Uint64::from_le_bytes(original); + assert_eq!(num.u64(), 1); + + // 258 + let original = [2, 1, 0, 0, 0, 0, 0, 0]; + let num = Uint64::from_le_bytes(original); + assert_eq!(num.u64(), 258); + + // 2x roundtrip + let original = [1; 8]; + let num = Uint64::from_le_bytes(original); + let a: [u8; 8] = num.to_le_bytes(); + assert_eq!(a, original); + + let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let num = Uint64::from_le_bytes(original); + let resulting_bytes: [u8; 8] = num.to_le_bytes(); + assert_eq!(resulting_bytes, original); + } + #[test] fn uint64_convert_into() { let original = Uint64(12345);