From 8e4e6b139f1bfcebf170095d246bf71777cf0fc9 Mon Sep 17 00:00:00 2001 From: yancy Date: Wed, 11 Dec 2024 15:22:43 -0600 Subject: [PATCH] Return result from method Conditionally returns a result depending on the input. This is in preparation for changing the MAX and MIN values of SignedAmount. --- units/src/amount/serde.rs | 4 +++- units/src/amount/signed.rs | 24 +++++++++++++++++++++--- units/src/amount/unsigned.rs | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/units/src/amount/serde.rs b/units/src/amount/serde.rs index 2caa8c74e7..afc4e02c78 100644 --- a/units/src/amount/serde.rs +++ b/units/src/amount/serde.rs @@ -135,7 +135,9 @@ impl SerdeAmount for SignedAmount { i64::serialize(&self.to_sat(), s) } fn des_sat<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result { - Ok(SignedAmount::from_sat(i64::deserialize(d)?)) + use serde::de::Error; + SignedAmount::from_sat(i64::deserialize(d)?) + .map_err(D::Error::custom) } #[cfg(feature = "alloc")] fn ser_btc(self, s: S, _: private::Token) -> Result { diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs index 69a6c340bf..cb7d67e117 100644 --- a/units/src/amount/signed.rs +++ b/units/src/amount/signed.rs @@ -63,7 +63,20 @@ impl SignedAmount { pub const MAX: SignedAmount = SignedAmount(i64::MAX); /// Constructs a new [`SignedAmount`] with satoshi precision and the given number of satoshis. - pub const fn from_sat(satoshi: i64) -> SignedAmount { SignedAmount(satoshi) } + /// + /// # Errors + /// + /// On values exceeding [`SignedAmount::MAX`] or less than [`SignedAmount::MIN`] + #[allow(clippy::absurd_extreme_comparisons)] + pub const fn from_sat(satoshi: i64) -> Result { + if satoshi < Self::MIN.0 { + Err(OutOfRangeError { is_signed: true, is_greater_than_max: false }) + } else if satoshi > Self::MAX.0 { + Err(OutOfRangeError { is_signed: true, is_greater_than_max: true }) + } else { + Ok(SignedAmount(satoshi)) + } + } /// Constructs a new [`SignedAmount`] with satoshi precision and the given number of satoshis. /// @@ -98,7 +111,7 @@ impl SignedAmount { /// per bitcoin overflows an `i64` type. pub fn from_int_btc(btc: i64) -> Result { match btc.checked_mul(100_000_000) { - Some(amount) => Ok(SignedAmount::from_sat(amount)), + Some(amount) => SignedAmount::from_sat(amount), None => Err(OutOfRangeError { is_signed: true, is_greater_than_max: true }), } } @@ -112,7 +125,12 @@ impl SignedAmount { /// per bitcoin overflows an `i64` type. pub const fn from_int_btc_const(btc: i64) -> SignedAmount { match btc.checked_mul(100_000_000) { - Some(amount) => SignedAmount::from_sat(amount), + Some(amount) => { + match SignedAmount::from_sat(amount) { + Ok(sa) => sa, + Err(_) => panic!("checked_mul overflow") + } + } None => panic!("checked_mul overflowed"), } } diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs index f51ae4af35..b57a568130 100644 --- a/units/src/amount/unsigned.rs +++ b/units/src/amount/unsigned.rs @@ -345,7 +345,7 @@ impl Amount { if self.to_sat() > SignedAmount::MAX.to_sat() as u64 { Err(OutOfRangeError::too_big(true)) } else { - Ok(SignedAmount::from_sat(self.to_sat() as i64)) + SignedAmount::from_sat(self.to_sat() as i64) } }