Skip to content

Commit 7ef262e

Browse files
authored
Merge pull request #2351 from CosmWasm/from_be_bytes-from_le_bytes
Implement from_be_bytes/from_le_bytes for Uint64 and Uint128
2 parents f503569 + 23de2fc commit 7ef262e

File tree

6 files changed

+271
-79
lines changed

6 files changed

+271
-79
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ and this project adheres to
1515
`From<Int128> for i128` ([#2268])
1616
- cosmwasm-std: Deprecate `abort` feature. The panic handler is now always
1717
enabled. ([#2337])
18+
- cosmwasm-std: Implement `Uint128::from_{be,le}_bytes` and
19+
`Uint64::from_{be,le}_bytes`. ([#2269])
1820

1921
[#2268]: https://github.com/CosmWasm/cosmwasm/issues/2268
2022
[#2337]: https://github.com/CosmWasm/cosmwasm/issues/2337
23+
[#2269]: https://github.com/CosmWasm/cosmwasm/issues/2269
2124

2225
## Fixed
2326

packages/std/src/math/conversion.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,35 @@ macro_rules! try_from_int_to_uint {
326326
}
327327
pub(crate) use try_from_int_to_uint;
328328

329+
macro_rules! from_and_to_bytes {
330+
($inner: ty, $byte_size: literal) => {
331+
/// Constructs new value from big endian bytes
332+
#[must_use]
333+
pub const fn from_be_bytes(data: [u8; $byte_size]) -> Self {
334+
Self(<$inner>::from_be_bytes(data))
335+
}
336+
337+
/// Constructs new value from little endian bytes
338+
#[must_use]
339+
pub const fn from_le_bytes(data: [u8; $byte_size]) -> Self {
340+
Self(<$inner>::from_le_bytes(data))
341+
}
342+
343+
/// Returns a copy of the number as big endian bytes.
344+
#[must_use = "this returns the result of the operation, without modifying the original"]
345+
pub const fn to_be_bytes(self) -> [u8; $byte_size] {
346+
self.0.to_be_bytes()
347+
}
348+
349+
/// Returns a copy of the number as little endian bytes.
350+
#[must_use = "this returns the result of the operation, without modifying the original"]
351+
pub const fn to_le_bytes(self) -> [u8; $byte_size] {
352+
self.0.to_le_bytes()
353+
}
354+
};
355+
}
356+
pub(crate) use from_and_to_bytes;
357+
329358
#[cfg(test)]
330359
mod tests {
331360
use super::*;

packages/std/src/math/int128.rs

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::{
1414
};
1515

1616
use super::conversion::{
17-
forward_try_from, primitive_to_wrapped_int, try_from_int_to_int, wrapped_int_to_primitive,
17+
forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, try_from_int_to_int,
18+
wrapped_int_to_primitive,
1819
};
1920
use super::impl_int_serde;
2021
use super::num_consts::NumConsts;
@@ -67,27 +68,7 @@ impl Int128 {
6768
self.0
6869
}
6970

70-
#[must_use]
71-
pub const fn from_be_bytes(data: [u8; 16]) -> Self {
72-
Self(i128::from_be_bytes(data))
73-
}
74-
75-
#[must_use]
76-
pub const fn from_le_bytes(data: [u8; 16]) -> Self {
77-
Self(i128::from_le_bytes(data))
78-
}
79-
80-
/// Returns a copy of the number as big endian bytes.
81-
#[must_use = "this returns the result of the operation, without modifying the original"]
82-
pub const fn to_be_bytes(self) -> [u8; 16] {
83-
self.0.to_be_bytes()
84-
}
85-
86-
/// Returns a copy of the number as little endian bytes.
87-
#[must_use = "this returns the result of the operation, without modifying the original"]
88-
pub const fn to_le_bytes(self) -> [u8; 16] {
89-
self.0.to_le_bytes()
90-
}
71+
from_and_to_bytes!(i128, 16);
9172

9273
#[must_use]
9374
pub const fn is_zero(&self) -> bool {
@@ -521,16 +502,64 @@ mod tests {
521502

522503
#[test]
523504
fn int128_from_be_bytes_works() {
524-
let num = Int128::from_be_bytes([1; 16]);
505+
// zero
506+
let original = [0; 16];
507+
let num = Int128::from_be_bytes(original);
508+
assert!(num.is_zero());
509+
510+
// one
511+
let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
512+
let num = Int128::from_be_bytes(original);
513+
assert_eq!(num.i128(), 1);
514+
515+
// 258
516+
let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2];
517+
let num = Int128::from_be_bytes(original);
518+
assert_eq!(num.i128(), 258);
519+
520+
// 2x roundtrip
521+
let original = [1; 16];
522+
let num = Int128::from_be_bytes(original);
525523
let a: [u8; 16] = num.to_be_bytes();
526-
assert_eq!(a, [1; 16]);
524+
assert_eq!(a, original);
527525

528-
let be_bytes = [
526+
let original = [
529527
0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
530528
];
531-
let num = Int128::from_be_bytes(be_bytes);
529+
let num = Int128::from_be_bytes(original);
532530
let resulting_bytes: [u8; 16] = num.to_be_bytes();
533-
assert_eq!(be_bytes, resulting_bytes);
531+
assert_eq!(resulting_bytes, original);
532+
}
533+
534+
#[test]
535+
fn int128_from_le_bytes_works() {
536+
// zero
537+
let original = [0; 16];
538+
let num = Int128::from_le_bytes(original);
539+
assert!(num.is_zero());
540+
541+
// one
542+
let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
543+
let num = Int128::from_le_bytes(original);
544+
assert_eq!(num.i128(), 1);
545+
546+
// 258
547+
let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
548+
let num = Int128::from_le_bytes(original);
549+
assert_eq!(num.i128(), 258);
550+
551+
// 2x roundtrip
552+
let original = [1; 16];
553+
let num = Int128::from_le_bytes(original);
554+
let a: [u8; 16] = num.to_le_bytes();
555+
assert_eq!(a, original);
556+
557+
let original = [
558+
0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
559+
];
560+
let num = Int128::from_le_bytes(original);
561+
let resulting_bytes: [u8; 16] = num.to_le_bytes();
562+
assert_eq!(resulting_bytes, original);
534563
}
535564

536565
#[test]

packages/std/src/math/int64.rs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::{
1414
};
1515

1616
use super::conversion::{
17-
forward_try_from, primitive_to_wrapped_int, try_from_int_to_int, wrapped_int_to_primitive,
17+
forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, try_from_int_to_int,
18+
wrapped_int_to_primitive,
1819
};
1920
use super::impl_int_serde;
2021
use super::num_consts::NumConsts;
@@ -67,27 +68,7 @@ impl Int64 {
6768
self.0
6869
}
6970

70-
#[must_use]
71-
pub const fn from_be_bytes(data: [u8; 8]) -> Self {
72-
Self(i64::from_be_bytes(data))
73-
}
74-
75-
#[must_use]
76-
pub const fn from_le_bytes(data: [u8; 8]) -> Self {
77-
Self(i64::from_le_bytes(data))
78-
}
79-
80-
/// Returns a copy of the number as big endian bytes.
81-
#[must_use = "this returns the result of the operation, without modifying the original"]
82-
pub const fn to_be_bytes(self) -> [u8; 8] {
83-
self.0.to_be_bytes()
84-
}
85-
86-
/// Returns a copy of the number as little endian bytes.
87-
#[must_use = "this returns the result of the operation, without modifying the original"]
88-
pub const fn to_le_bytes(self) -> [u8; 8] {
89-
self.0.to_le_bytes()
90-
}
71+
from_and_to_bytes!(i64, 8);
9172

9273
#[must_use]
9374
pub const fn is_zero(&self) -> bool {
@@ -511,14 +492,60 @@ mod tests {
511492

512493
#[test]
513494
fn int64_from_be_bytes_works() {
514-
let num = Int64::from_be_bytes([1; 8]);
495+
// zero
496+
let original = [0; 8];
497+
let num = Int64::from_be_bytes(original);
498+
assert!(num.is_zero());
499+
500+
// one
501+
let original = [0, 0, 0, 0, 0, 0, 0, 1];
502+
let num = Int64::from_be_bytes(original);
503+
assert_eq!(num.i64(), 1);
504+
505+
// 258
506+
let original = [0, 0, 0, 0, 0, 0, 1, 2];
507+
let num = Int64::from_be_bytes(original);
508+
assert_eq!(num.i64(), 258);
509+
510+
// 2x roundtrip
511+
let original = [1; 8];
512+
let num = Int64::from_be_bytes(original);
515513
let a: [u8; 8] = num.to_be_bytes();
516-
assert_eq!(a, [1; 8]);
514+
assert_eq!(a, original);
517515

518-
let be_bytes = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8];
519-
let num = Int64::from_be_bytes(be_bytes);
520-
let resulting_bytes: [u8; 8] = num.to_be_bytes();
521-
assert_eq!(be_bytes, resulting_bytes);
516+
let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8];
517+
let num = Int64::from_be_bytes(original);
518+
let a: [u8; 8] = num.to_be_bytes();
519+
assert_eq!(a, original);
520+
}
521+
522+
#[test]
523+
fn int64_from_le_bytes_works() {
524+
// zero
525+
let original = [0; 8];
526+
let num = Int64::from_le_bytes(original);
527+
assert!(num.is_zero());
528+
529+
// one
530+
let original = [1, 0, 0, 0, 0, 0, 0, 0];
531+
let num = Int64::from_le_bytes(original);
532+
assert_eq!(num.i64(), 1);
533+
534+
// 258
535+
let original = [2, 1, 0, 0, 0, 0, 0, 0];
536+
let num = Int64::from_le_bytes(original);
537+
assert_eq!(num.i64(), 258);
538+
539+
// 2x roundtrip
540+
let original = [1; 8];
541+
let num = Int64::from_le_bytes(original);
542+
let a: [u8; 8] = num.to_le_bytes();
543+
assert_eq!(a, original);
544+
545+
let original = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8];
546+
let num = Int64::from_le_bytes(original);
547+
let a: [u8; 8] = num.to_le_bytes();
548+
assert_eq!(a, original);
522549
}
523550

524551
#[test]

packages/std/src/math/uint128.rs

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use crate::{
1616
Uint256, Uint64,
1717
};
1818

19-
use super::conversion::{forward_try_from, primitive_to_wrapped_int, wrapped_int_to_primitive};
19+
use super::conversion::{
20+
forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, wrapped_int_to_primitive,
21+
};
2022
use super::impl_int_serde;
2123
use super::num_consts::NumConsts;
2224

@@ -73,17 +75,7 @@ impl Uint128 {
7375
self.0
7476
}
7577

76-
/// Returns a copy of the number as big endian bytes.
77-
#[must_use = "this returns the result of the operation, without modifying the original"]
78-
pub const fn to_be_bytes(self) -> [u8; 16] {
79-
self.0.to_be_bytes()
80-
}
81-
82-
/// Returns a copy of the number as little endian bytes.
83-
#[must_use = "this returns the result of the operation, without modifying the original"]
84-
pub const fn to_le_bytes(self) -> [u8; 16] {
85-
self.0.to_le_bytes()
86-
}
78+
from_and_to_bytes!(u128, 16);
8779

8880
#[must_use]
8981
pub const fn is_zero(&self) -> bool {
@@ -605,6 +597,68 @@ mod tests {
605597
);
606598
}
607599

600+
#[test]
601+
fn uint128_from_be_bytes_works() {
602+
// zero
603+
let original = [0; 16];
604+
let num = Uint128::from_be_bytes(original);
605+
assert!(num.is_zero());
606+
607+
// one
608+
let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
609+
let num = Uint128::from_be_bytes(original);
610+
assert_eq!(num.u128(), 1);
611+
612+
// 258
613+
let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2];
614+
let num = Uint128::from_be_bytes(original);
615+
assert_eq!(num.u128(), 258);
616+
617+
// 2x roundtrip
618+
let original = [1; 16];
619+
let num = Uint128::from_be_bytes(original);
620+
let a: [u8; 16] = num.to_be_bytes();
621+
assert_eq!(a, original);
622+
623+
let original = [
624+
0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
625+
];
626+
let num = Uint128::from_be_bytes(original);
627+
let resulting_bytes: [u8; 16] = num.to_be_bytes();
628+
assert_eq!(resulting_bytes, original);
629+
}
630+
631+
#[test]
632+
fn uint128_from_le_bytes_works() {
633+
// zero
634+
let original = [0; 16];
635+
let num = Uint128::from_le_bytes(original);
636+
assert!(num.is_zero());
637+
638+
// one
639+
let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
640+
let num = Uint128::from_le_bytes(original);
641+
assert_eq!(num.u128(), 1);
642+
643+
// 258
644+
let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
645+
let num = Uint128::from_le_bytes(original);
646+
assert_eq!(num.u128(), 258);
647+
648+
// 2x roundtrip
649+
let original = [1; 16];
650+
let num = Uint128::from_le_bytes(original);
651+
let a: [u8; 16] = num.to_le_bytes();
652+
assert_eq!(a, original);
653+
654+
let original = [
655+
0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
656+
];
657+
let num = Uint128::from_le_bytes(original);
658+
let resulting_bytes: [u8; 16] = num.to_le_bytes();
659+
assert_eq!(resulting_bytes, original);
660+
}
661+
608662
#[test]
609663
fn uint128_convert_into() {
610664
let original = Uint128(12345);

0 commit comments

Comments
 (0)