units: Flatten nested checked_ops methods
What changed, and why it matters
This commit is a straightforward code cleanup in the rust-bitcoin library. It replaces deeply nested match blocks with newer, cleaner Rust syntax (let-else statements) inside safe arithmetic helper functions. The actual behavior of the code—checking for overflow and returning None on error—does not change. There is no security vulnerability being fixed here.
No security action required. Treat as a normal readability/style refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors const checked arithmetic methods in Amount, SignedAmount, FeeRate, and Weight modules. It replaces nested match expressions with let-else bindings, which were not usable in const contexts on older Rust versions. The control flow and semantics remain identical: each method still performs a checked primitive operation, validates the result, and returns Some(value) or None. No bounds checks, validation logic, or return values are altered.
Changed components
units/src/amount/signed.rsunits/src/amount/unsigned.rsunits/src/fee_rate/mod.rsunits/src/weight.rsInspect captured patch +53 / −127
diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs
index e90ce2a4..ff61d0ea 100644
--- a/units/src/amount/signed.rs
+++ b/units/src/amount/signed.rs
@@ -434,14 +434,9 @@ impl SignedAmount {
#[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_add(rhs.to_sat()) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None,
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_add(rhs.to_sat()) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked subtraction.
@@ -451,14 +446,9 @@ impl SignedAmount {
#[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_sub(rhs.to_sat()) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None,
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_sub(rhs.to_sat()) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked multiplication.
@@ -468,14 +458,9 @@ impl SignedAmount {
#[inline]
#[must_use]
pub const fn checked_mul(self, rhs: i64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_mul(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None,
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_mul(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked integer division.
@@ -486,14 +471,9 @@ impl SignedAmount {
#[inline]
#[must_use]
pub const fn checked_div(self, rhs: i64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_div(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None, // Unreachable because of checked_div above.
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_div(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked remainder.
@@ -502,14 +482,9 @@ impl SignedAmount {
#[inline]
#[must_use]
pub const fn checked_rem(self, rhs: i64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_rem(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None, // Unreachable because of checked_rem above.
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_rem(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Subtraction that doesn't allow negative [`SignedAmount`]s.
diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs
index 6dc7b71d..8aae5165 100644
--- a/units/src/amount/unsigned.rs
+++ b/units/src/amount/unsigned.rs
@@ -383,12 +383,9 @@ impl Amount {
#[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
// Unchecked add ok, adding two values less than `MAX_MONEY` cannot overflow an `i64`.
- match Self::from_sat(self.to_sat() + rhs.to_sat()) {
- Ok(amount) => Some(amount),
- Err(_) => None,
- }
+ let Ok(amount) = Self::from_sat(self.to_sat() + rhs.to_sat()) else { return None };
+ Some(amount)
}
/// Checked subtraction.
@@ -397,14 +394,9 @@ impl Amount {
#[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_sub(rhs.to_sat()) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None, // Unreachable because of checked_sub above.
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_sub(rhs.to_sat()) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked multiplication.
@@ -413,14 +405,9 @@ impl Amount {
#[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_mul(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None,
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_mul(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked integer division.
@@ -431,14 +418,9 @@ impl Amount {
#[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_div(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None, // Unreachable because of checked_div above.
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_div(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Checked remainder.
@@ -447,14 +429,9 @@ impl Amount {
#[inline]
#[must_use]
pub const fn checked_rem(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat().checked_rem(rhs) {
- Some(res) => match Self::from_sat(res) {
- Ok(amount) => Some(amount),
- Err(_) => None, // Unreachable because of checked_rem above.
- },
- None => None,
- }
+ let Some(sat) = self.to_sat().checked_rem(rhs) else { return None };
+ let Ok(amount) = Self::from_sat(sat) else { return None };
+ Some(amount)
}
/// Converts to a signed amount.
diff --git a/units/src/fee_rate/mod.rs b/units/src/fee_rate/mod.rs
index 0f82096c..e39bf20d 100644
--- a/units/src/fee_rate/mod.rs
+++ b/units/src/fee_rate/mod.rs
@@ -144,11 +144,8 @@ impl FeeRate {
#[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat_per_mvb().checked_mul(rhs) {
- Some(res) => Some(Self::from_sat_per_mvb(res)),
- None => None,
- }
+ let Some(sat_mvb) = self.to_sat_per_mvb().checked_mul(rhs) else { return None };
+ Some(Self::from_sat_per_mvb(sat_mvb))
}
/// Checked division.
@@ -157,11 +154,8 @@ impl FeeRate {
#[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat_per_mvb().checked_div(rhs) {
- Some(res) => Some(Self::from_sat_per_mvb(res)),
- None => None,
- }
+ let Some(sat_mvb) = self.to_sat_per_mvb().checked_div(rhs) else { return None };
+ Some(Self::from_sat_per_mvb(sat_mvb))
}
/// Checked addition.
@@ -170,11 +164,10 @@ impl FeeRate {
#[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat_per_mvb().checked_add(rhs.to_sat_per_mvb()) {
- Some(res) => Some(Self::from_sat_per_mvb(res)),
- None => None,
- }
+ let Some(sat_mvb) = self.to_sat_per_mvb().checked_add(rhs.to_sat_per_mvb()) else {
+ return None;
+ };
+ Some(Self::from_sat_per_mvb(sat_mvb))
}
/// Checked subtraction.
@@ -183,11 +176,10 @@ impl FeeRate {
#[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_sat_per_mvb().checked_sub(rhs.to_sat_per_mvb()) {
- Some(res) => Some(Self::from_sat_per_mvb(res)),
- None => None,
- }
+ let Some(sat_mvb) = self.to_sat_per_mvb().checked_sub(rhs.to_sat_per_mvb()) else {
+ return None;
+ };
+ Some(Self::from_sat_per_mvb(sat_mvb))
}
/// Calculates the fee by multiplying this fee rate by weight.
diff --git a/units/src/weight.rs b/units/src/weight.rs
index 2062e13e..d42d6420 100644
--- a/units/src/weight.rs
+++ b/units/src/weight.rs
@@ -65,21 +65,15 @@ impl Weight {
/// Constructs a new [`Weight`] from kilo weight units returning [`None`] if an overflow occurred.
#[inline]
pub const fn from_kwu(wu: u64) -> Option<Self> {
- // No `map()` in const context.
- match wu.checked_mul(1000) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = wu.checked_mul(1000) else { return None };
+ Some(Self::from_wu(wu))
}
/// Constructs a new [`Weight`] from virtual bytes, returning [`None`] if an overflow occurred.
#[inline]
pub const fn from_vb(vb: u64) -> Option<Self> {
- // No `map()` in const context.
- match vb.checked_mul(Self::WITNESS_SCALE_FACTOR) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = vb.checked_mul(Self::WITNESS_SCALE_FACTOR) else { return None };
+ Some(Self::from_wu(wu))
}
/// Constructs a new [`Weight`] from virtual bytes without an overflow check.
@@ -138,11 +132,8 @@ impl Weight {
#[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_wu().checked_add(rhs.to_wu()) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = self.to_wu().checked_add(rhs.to_wu()) else { return None };
+ Some(Self::from_wu(wu))
}
/// Checked subtraction.
@@ -151,11 +142,8 @@ impl Weight {
#[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- // No `map()` in const context.
- match self.to_wu().checked_sub(rhs.to_wu()) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = self.to_wu().checked_sub(rhs.to_wu()) else { return None };
+ Some(Self::from_wu(wu))
}
/// Checked multiplication.
@@ -164,11 +152,8 @@ impl Weight {
#[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_wu().checked_mul(rhs) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = self.to_wu().checked_mul(rhs) else { return None };
+ Some(Self::from_wu(wu))
}
/// Checked division.
@@ -177,11 +162,8 @@ impl Weight {
#[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
- // No `map()` in const context.
- match self.to_wu().checked_div(rhs) {
- Some(wu) => Some(Self::from_wu(wu)),
- None => None,
- }
+ let Some(wu) = self.to_wu().checked_div(rhs) else { return None };
+ Some(Self::from_wu(wu))
}
/// Checked fee rate multiplication.
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.