From f4fede39d8cf995828a038787446afb702da2c26 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. --- api/units/all-features.txt | 2 +- api/units/alloc-only.txt | 2 +- api/units/no-features.txt | 2 +- units/src/amount/serde.rs | 4 +++- units/src/amount/signed.rs | 23 ++++++++++++++++++++--- units/src/amount/unsigned.rs | 2 +- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/api/units/all-features.txt b/api/units/all-features.txt index bf983e8a9c..52e4f29c3a 100644 --- a/api/units/all-features.txt +++ b/api/units/all-features.txt @@ -697,7 +697,7 @@ pub const fn bitcoin_units::SignedAmount::checked_mul(self, rhs: i64) -> core::o pub const fn bitcoin_units::SignedAmount::checked_rem(self, rhs: i64) -> core::option::Option pub const fn bitcoin_units::SignedAmount::checked_sub(self, rhs: bitcoin_units::SignedAmount) -> core::option::Option pub const fn bitcoin_units::SignedAmount::from_int_btc_const(btc: i64) -> bitcoin_units::SignedAmount -pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> bitcoin_units::SignedAmount +pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> core::result::Result pub const fn bitcoin_units::SignedAmount::from_sat_unchecked(satoshi: i64) -> bitcoin_units::SignedAmount pub const fn bitcoin_units::SignedAmount::to_sat(self) -> i64 pub const fn bitcoin_units::block::BlockHeight::from_u32(inner: u32) -> Self diff --git a/api/units/alloc-only.txt b/api/units/alloc-only.txt index 737ee30385..22e630a658 100644 --- a/api/units/alloc-only.txt +++ b/api/units/alloc-only.txt @@ -655,7 +655,7 @@ pub const fn bitcoin_units::SignedAmount::checked_mul(self, rhs: i64) -> core::o pub const fn bitcoin_units::SignedAmount::checked_rem(self, rhs: i64) -> core::option::Option pub const fn bitcoin_units::SignedAmount::checked_sub(self, rhs: bitcoin_units::SignedAmount) -> core::option::Option pub const fn bitcoin_units::SignedAmount::from_int_btc_const(btc: i64) -> bitcoin_units::SignedAmount -pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> bitcoin_units::SignedAmount +pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> core::result::Result pub const fn bitcoin_units::SignedAmount::from_sat_unchecked(satoshi: i64) -> bitcoin_units::SignedAmount pub const fn bitcoin_units::SignedAmount::to_sat(self) -> i64 pub const fn bitcoin_units::block::BlockHeight::from_u32(inner: u32) -> Self diff --git a/api/units/no-features.txt b/api/units/no-features.txt index b41ab18c8e..373832f3f7 100644 --- a/api/units/no-features.txt +++ b/api/units/no-features.txt @@ -637,7 +637,7 @@ pub const fn bitcoin_units::SignedAmount::checked_mul(self, rhs: i64) -> core::o pub const fn bitcoin_units::SignedAmount::checked_rem(self, rhs: i64) -> core::option::Option pub const fn bitcoin_units::SignedAmount::checked_sub(self, rhs: bitcoin_units::SignedAmount) -> core::option::Option pub const fn bitcoin_units::SignedAmount::from_int_btc_const(btc: i64) -> bitcoin_units::SignedAmount -pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> bitcoin_units::SignedAmount +pub const fn bitcoin_units::SignedAmount::from_sat(satoshi: i64) -> core::result::Result pub const fn bitcoin_units::SignedAmount::from_sat_unchecked(satoshi: i64) -> bitcoin_units::SignedAmount pub const fn bitcoin_units::SignedAmount::to_sat(self) -> i64 pub const fn bitcoin_units::block::BlockHeight::from_u32(inner: u32) -> Self 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 bbfe31f1e5..1dd31527ec 100644 --- a/units/src/amount/signed.rs +++ b/units/src/amount/signed.rs @@ -63,7 +63,19 @@ impl SignedAmount { pub const MAX: Self = SignedAmount::MAX_MONEY; /// 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`] + 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. /// @@ -97,7 +109,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 }), } } @@ -111,7 +123,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 8fa95eeced..282325ee49 100644 --- a/units/src/amount/unsigned.rs +++ b/units/src/amount/unsigned.rs @@ -415,7 +415,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) } }