Skip to content

Commit 547efed

Browse files
committed
Add panicking_sub to Uint64/Uint128/Uint256/Uint512
1 parent 5b4adab commit 547efed

File tree

5 files changed

+110
-16
lines changed

5 files changed

+110
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ and this project adheres to
2323
`Uint512::add` ([#2092])
2424
- cosmwasm-std: Add `{CosmosMsg,SubMsg,Response}::change_custom` to change the
2525
custom message type ([#2099])
26+
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_sub` which is like the
27+
`Sub` implementation but `const`.
2628

2729
[#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983
2830
[#2057]: https://github.com/CosmWasm/cosmwasm/pull/2057

packages/core/src/math/uint128.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,17 @@ impl Uint128 {
263263
Self(self.0.saturating_pow(exp))
264264
}
265265

266+
/// This is the same as [`Uint128::sub`] but const.
267+
///
268+
/// Panics on overflow.
269+
#[must_use = "this returns the result of the operation, without modifying the original"]
270+
pub const fn panicking_sub(self, other: Self) -> Self {
271+
match self.0.checked_sub(other.u128()) {
272+
None => panic!("attempt to subtract with overflow"),
273+
Some(diff) => Self(diff),
274+
}
275+
}
276+
266277
#[must_use = "this returns the result of the operation, without modifying the original"]
267278
pub const fn abs_diff(self, other: Self) -> Self {
268279
Self(if self.0 < other.0 {
@@ -385,11 +396,7 @@ impl Sub<Uint128> for Uint128 {
385396
type Output = Self;
386397

387398
fn sub(self, rhs: Self) -> Self {
388-
Uint128(
389-
self.u128()
390-
.checked_sub(rhs.u128())
391-
.expect("attempt to subtract with overflow"),
392-
)
399+
self.panicking_sub(rhs)
393400
}
394401
}
395402
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
@@ -1176,6 +1183,21 @@ mod tests {
11761183
assert_eq!(a, Uint128::from(1u32));
11771184
}
11781185

1186+
#[test]
1187+
fn uint128_panicking_sub_works() {
1188+
let a = Uint128::new(5);
1189+
let b = Uint128::new(3);
1190+
assert_eq!(a.panicking_sub(b), Uint128::new(2));
1191+
}
1192+
1193+
#[test]
1194+
#[should_panic(expected = "attempt to subtract with overflow")]
1195+
fn uint128_panicking_sub_panics_on_overflow() {
1196+
let a = Uint128::ZERO;
1197+
let b = Uint128::ONE;
1198+
let _diff = a.panicking_sub(b);
1199+
}
1200+
11791201
#[test]
11801202
fn uint128_abs_diff_works() {
11811203
let a = Uint128::from(42u32);

packages/core/src/math/uint256.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,17 @@ impl Uint256 {
335335
Self(self.0.saturating_pow(exp))
336336
}
337337

338+
/// This is the same as [`Uint256::sub`] but const.
339+
///
340+
/// Panics on overflow.
341+
#[must_use = "this returns the result of the operation, without modifying the original"]
342+
pub const fn panicking_sub(self, other: Self) -> Self {
343+
match self.0.checked_sub(other.0) {
344+
None => panic!("attempt to subtract with overflow"),
345+
Some(diff) => Self(diff),
346+
}
347+
}
348+
338349
#[must_use = "this returns the result of the operation, without modifying the original"]
339350
pub const fn abs_diff(self, other: Self) -> Self {
340351
Self(self.0.abs_diff(other.0))
@@ -455,11 +466,7 @@ impl Sub<Uint256> for Uint256 {
455466
type Output = Self;
456467

457468
fn sub(self, rhs: Self) -> Self {
458-
Self(
459-
self.0
460-
.checked_sub(rhs.0)
461-
.expect("attempt to subtract with overflow"),
462-
)
469+
self.panicking_sub(rhs)
463470
}
464471
}
465472
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
@@ -1725,6 +1732,21 @@ mod tests {
17251732
assert_eq!(a, Uint256::from(1u32));
17261733
}
17271734

1735+
#[test]
1736+
fn uint256_panicking_sub_works() {
1737+
let a = Uint256::from(5u32);
1738+
let b = Uint256::from(3u32);
1739+
assert_eq!(a.panicking_sub(b), Uint256::from(2u32));
1740+
}
1741+
1742+
#[test]
1743+
#[should_panic(expected = "attempt to subtract with overflow")]
1744+
fn uint256_panicking_sub_panics_on_overflow() {
1745+
let a = Uint256::ZERO;
1746+
let b = Uint256::ONE;
1747+
let _diff = a.panicking_sub(b);
1748+
}
1749+
17281750
#[test]
17291751
fn uint256_abs_diff_works() {
17301752
let a = Uint256::from(42u32);

packages/core/src/math/uint512.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,17 @@ impl Uint512 {
298298
Self(self.0.saturating_pow(exp))
299299
}
300300

301+
/// This is the same as [`Uint512::sub`] but const.
302+
///
303+
/// Panics on overflow.
304+
#[must_use = "this returns the result of the operation, without modifying the original"]
305+
pub const fn panicking_sub(self, other: Self) -> Self {
306+
match self.0.checked_sub(other.0) {
307+
None => panic!("attempt to subtract with overflow"),
308+
Some(diff) => Self(diff),
309+
}
310+
}
311+
301312
#[must_use = "this returns the result of the operation, without modifying the original"]
302313
pub const fn abs_diff(self, other: Self) -> Self {
303314
Self(self.0.abs_diff(other.0))
@@ -434,7 +445,7 @@ impl Sub<Uint512> for Uint512 {
434445
type Output = Self;
435446

436447
fn sub(self, rhs: Self) -> Self {
437-
Uint512(self.0.checked_sub(rhs.0).unwrap())
448+
self.panicking_sub(rhs)
438449
}
439450
}
440451
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
@@ -1370,6 +1381,21 @@ mod tests {
13701381
assert_eq!(a, Uint512::from(1u32));
13711382
}
13721383

1384+
#[test]
1385+
fn uint512_panicking_sub_works() {
1386+
let a = Uint512::from(5u32);
1387+
let b = Uint512::from(3u32);
1388+
assert_eq!(a.panicking_sub(b), Uint512::from(2u32));
1389+
}
1390+
1391+
#[test]
1392+
#[should_panic(expected = "attempt to subtract with overflow")]
1393+
fn uint512_panicking_sub_panics_on_overflow() {
1394+
let a = Uint512::ZERO;
1395+
let b = Uint512::ONE;
1396+
let _diff = a.panicking_sub(b);
1397+
}
1398+
13731399
#[test]
13741400
fn uint512_abs_diff_works() {
13751401
let a = Uint512::from(42u32);

packages/core/src/math/uint64.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,17 @@ impl Uint64 {
257257
Self(self.0.saturating_pow(exp))
258258
}
259259

260+
/// This is the same as [`Uint64::sub`] but const.
261+
///
262+
/// Panics on overflow.
263+
#[must_use = "this returns the result of the operation, without modifying the original"]
264+
pub const fn panicking_sub(self, other: Self) -> Self {
265+
match self.0.checked_sub(other.u64()) {
266+
None => panic!("attempt to subtract with overflow"),
267+
Some(diff) => Self(diff),
268+
}
269+
}
270+
260271
#[must_use = "this returns the result of the operation, without modifying the original"]
261272
pub const fn abs_diff(self, other: Self) -> Self {
262273
Self(if self.0 < other.0 {
@@ -358,11 +369,7 @@ impl Sub<Uint64> for Uint64 {
358369
type Output = Self;
359370

360371
fn sub(self, rhs: Self) -> Self {
361-
Uint64(
362-
self.u64()
363-
.checked_sub(rhs.u64())
364-
.expect("attempt to subtract with overflow"),
365-
)
372+
self.panicking_sub(rhs)
366373
}
367374
}
368375
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
@@ -1090,6 +1097,21 @@ mod tests {
10901097
assert_eq!(a, Uint64::from(1u32));
10911098
}
10921099

1100+
#[test]
1101+
fn uint64_panicking_sub_works() {
1102+
let a = Uint64::new(5);
1103+
let b = Uint64::new(3);
1104+
assert_eq!(a.panicking_sub(b), Uint64::new(2));
1105+
}
1106+
1107+
#[test]
1108+
#[should_panic(expected = "attempt to subtract with overflow")]
1109+
fn uint64_panicking_sub_panics_on_overflow() {
1110+
let a = Uint64::ZERO;
1111+
let b = Uint64::ONE;
1112+
let _diff = a.panicking_sub(b);
1113+
}
1114+
10931115
#[test]
10941116
fn uint64_abs_diff_works() {
10951117
let a = Uint64::from(42u32);

0 commit comments

Comments
 (0)