amount: move MIN/MAX constants and constructors inside the privacy boundary
It's conceptually a bit tortured to have an `Amount` type defined in a private module, with an _unchecked method allowing you to set values out of range, which needs to be used outside of the module to *define* the range and the constructors that check it. Move the constants and constructors inside the privacy module, where they can be written directly. This is easier to understand and eliminates a couple _unchecked calls.
This commit is contained in:
parent
004d073184
commit
d0d7a15604
|
@ -17,6 +17,8 @@ use super::{
|
|||
};
|
||||
|
||||
mod encapsulate {
|
||||
use super::OutOfRangeError;
|
||||
|
||||
/// A signed amount.
|
||||
///
|
||||
/// The [`SignedAmount`] type can be used to express Bitcoin amounts that support arithmetic and
|
||||
|
@ -50,6 +52,11 @@ mod encapsulate {
|
|||
pub struct SignedAmount(i64);
|
||||
|
||||
impl SignedAmount {
|
||||
/// The maximum value of an amount.
|
||||
pub const MAX: Self = Self(21_000_000 * 100_000_000);
|
||||
/// The minimum value of an amount.
|
||||
pub const MIN: Self = Self(-21_000_000 * 100_000_000);
|
||||
|
||||
/// Constructs a new [`SignedAmount`] with satoshi precision and the given number of satoshis.
|
||||
///
|
||||
/// Caller to guarantee that `satoshi` is within valid range.
|
||||
|
@ -74,6 +81,31 @@ mod encapsulate {
|
|||
/// assert_eq!(SignedAmount::ONE_BTC.to_sat(), 100_000_000);
|
||||
/// ```
|
||||
pub const fn to_sat(self) -> i64 { self.0 }
|
||||
|
||||
/// Constructs a new [`SignedAmount`] from the given number of satoshis.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If `satoshi` is outside of valid range (see [`Self::MAX_MONEY`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitcoin_units::{amount, SignedAmount};
|
||||
/// # let sat = -100_000;
|
||||
/// let amount = SignedAmount::from_sat(sat)?;
|
||||
/// assert_eq!(amount.to_sat(), sat);
|
||||
/// # Ok::<_, amount::OutOfRangeError>(())
|
||||
/// ```
|
||||
pub const fn from_sat(satoshi: i64) -> Result<SignedAmount, OutOfRangeError> {
|
||||
if satoshi < Self::MIN.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: true, is_greater_than_max: false })
|
||||
} else if satoshi > Self::MAX_MONEY.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: true, is_greater_than_max: true })
|
||||
} else {
|
||||
Ok(Self(satoshi))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[doc(inline)]
|
||||
|
@ -89,36 +121,7 @@ impl SignedAmount {
|
|||
/// Exactly fifty bitcoin.
|
||||
pub const FIFTY_BTC: Self = SignedAmount::from_btc_i16(50);
|
||||
/// The maximum value allowed as an amount. Useful for sanity checking.
|
||||
pub const MAX_MONEY: Self = SignedAmount::from_sat_unchecked(21_000_000 * 100_000_000);
|
||||
/// The minimum value of an amount.
|
||||
pub const MIN: Self = SignedAmount::from_sat_unchecked(-21_000_000 * 100_000_000);
|
||||
/// The maximum value of an amount.
|
||||
pub const MAX: Self = SignedAmount::MAX_MONEY;
|
||||
|
||||
/// Constructs a new [`SignedAmount`] from the given number of satoshis.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If `satoshi` is outside of valid range (see [`Self::MAX_MONEY`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitcoin_units::{amount, SignedAmount};
|
||||
/// # let sat = -100_000;
|
||||
/// let amount = SignedAmount::from_sat(sat)?;
|
||||
/// assert_eq!(amount.to_sat(), sat);
|
||||
/// # Ok::<_, amount::OutOfRangeError>(())
|
||||
/// ```
|
||||
pub const fn from_sat(satoshi: i64) -> Result<SignedAmount, OutOfRangeError> {
|
||||
if satoshi < Self::MIN.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: true, is_greater_than_max: false })
|
||||
} else if satoshi > Self::MAX_MONEY.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: true, is_greater_than_max: true })
|
||||
} else {
|
||||
Ok(SignedAmount::from_sat_unchecked(satoshi))
|
||||
}
|
||||
}
|
||||
pub const MAX_MONEY: Self = Self::MAX;
|
||||
|
||||
/// Converts from a value expressing a decimal number of bitcoin to a [`SignedAmount`].
|
||||
///
|
||||
|
|
|
@ -17,6 +17,8 @@ use super::{
|
|||
};
|
||||
|
||||
mod encapsulate {
|
||||
use super::OutOfRangeError;
|
||||
|
||||
/// An amount.
|
||||
///
|
||||
/// The [`Amount`] type can be used to express Bitcoin amounts that support arithmetic and
|
||||
|
@ -50,6 +52,11 @@ mod encapsulate {
|
|||
pub struct Amount(u64);
|
||||
|
||||
impl Amount {
|
||||
/// The maximum value of an amount.
|
||||
pub const MAX: Self = Self(21_000_000 * 100_000_000);
|
||||
/// The minimum value of an amount.
|
||||
pub const MIN: Self = Self(0);
|
||||
|
||||
/// Constructs a new [`Amount`] with satoshi precision and the given number of satoshis.
|
||||
///
|
||||
/// Caller to guarantee that `satoshi` is within valid range. See [`Self::MAX`].
|
||||
|
@ -72,6 +79,29 @@ mod encapsulate {
|
|||
/// assert_eq!(Amount::ONE_BTC.to_sat(), 100_000_000);
|
||||
/// ```
|
||||
pub const fn to_sat(self) -> u64 { self.0 }
|
||||
|
||||
/// Constructs a new [`Amount`] from the given number of satoshis.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If `satoshi` is outside of valid range (greater than [`Self::MAX_MONEY`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitcoin_units::{amount, Amount};
|
||||
/// # let sat = 100_000;
|
||||
/// let amount = Amount::from_sat(sat)?;
|
||||
/// assert_eq!(amount.to_sat(), sat);
|
||||
/// # Ok::<_, amount::OutOfRangeError>(())
|
||||
/// ```
|
||||
pub const fn from_sat(satoshi: u64) -> Result<Amount, OutOfRangeError> {
|
||||
if satoshi > Self::MAX_MONEY.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: false, is_greater_than_max: true })
|
||||
} else {
|
||||
Ok(Self(satoshi))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[doc(inline)]
|
||||
|
@ -87,37 +117,10 @@ impl Amount {
|
|||
/// Exactly fifty bitcoin.
|
||||
pub const FIFTY_BTC: Self = Amount::from_btc_u16(50);
|
||||
/// The maximum value allowed as an amount. Useful for sanity checking.
|
||||
pub const MAX_MONEY: Self = Amount::from_sat_unchecked(21_000_000 * 100_000_000);
|
||||
/// The minimum value of an amount.
|
||||
pub const MIN: Self = Amount::ZERO;
|
||||
/// The maximum value of an amount.
|
||||
pub const MAX: Self = Amount::MAX_MONEY;
|
||||
pub const MAX_MONEY: Self = Amount::MAX;
|
||||
/// The number of bytes that an amount contributes to the size of a transaction.
|
||||
pub const SIZE: usize = 8; // Serialized length of a u64.
|
||||
|
||||
/// Constructs a new [`Amount`] from the given number of satoshis.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If `satoshi` is outside of valid range (greater than [`Self::MAX_MONEY`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitcoin_units::{amount, Amount};
|
||||
/// # let sat = 100_000;
|
||||
/// let amount = Amount::from_sat(sat)?;
|
||||
/// assert_eq!(amount.to_sat(), sat);
|
||||
/// # Ok::<_, amount::OutOfRangeError>(())
|
||||
/// ```
|
||||
pub const fn from_sat(satoshi: u64) -> Result<Amount, OutOfRangeError> {
|
||||
if satoshi > Self::MAX_MONEY.to_sat() {
|
||||
Err(OutOfRangeError { is_signed: false, is_greater_than_max: true })
|
||||
} else {
|
||||
Ok(Self::from_sat_unchecked(satoshi))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from a value expressing a decimal number of bitcoin to an [`Amount`].
|
||||
///
|
||||
/// # Errors
|
||||
|
|
Loading…
Reference in New Issue