units: Make from_int_btc_const take a 16 bit integer
The `from_int_btc_const` constructors are specifically designed for easily creating amount types in const context but currently they return an error which is annoying to handle in const context. If we make the `whole_bitcoin` parameter a 16 bit integer this gives us a nicer const constructor with the downside that it can only create values upto a maximum of - unsigned: 65_536 - signed: 32_767 That is plenty high enough for most use cases. Then use the new `from_int_btc_const` in associated consts. Note that because `from_sat` checks max (and min) values we must define max and min from sats directly.
This commit is contained in:
parent
cfccd389a9
commit
2ec1c2a044
|
@ -77,9 +77,9 @@ impl SignedAmount {
|
||||||
/// Exactly one satoshi.
|
/// Exactly one satoshi.
|
||||||
pub const ONE_SAT: Self = SignedAmount::from_sat_unchecked(1);
|
pub const ONE_SAT: Self = SignedAmount::from_sat_unchecked(1);
|
||||||
/// Exactly one bitcoin.
|
/// Exactly one bitcoin.
|
||||||
pub const ONE_BTC: Self = SignedAmount::from_sat_unchecked(100_000_000);
|
pub const ONE_BTC: Self = SignedAmount::from_int_btc_const(1);
|
||||||
/// Exactly fifty bitcoin.
|
/// Exactly fifty bitcoin.
|
||||||
pub const FIFTY_BTC: Self = SignedAmount::from_sat_unchecked(50 * 100_000_000);
|
pub const FIFTY_BTC: Self = SignedAmount::from_int_btc_const(50);
|
||||||
/// The maximum value allowed as an amount. Useful for sanity checking.
|
/// 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);
|
pub const MAX_MONEY: Self = SignedAmount::from_sat_unchecked(21_000_000 * 100_000_000);
|
||||||
/// The minimum value of an amount.
|
/// The minimum value of an amount.
|
||||||
|
@ -134,27 +134,21 @@ impl SignedAmount {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`].
|
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`].
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// If `whole_bitcoin` is greater than `21_000_000`.
|
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub fn from_int_btc<T: Into<i32>>(whole_bitcoin: T) -> Result<SignedAmount, OutOfRangeError> {
|
pub fn from_int_btc<T: Into<i16>>(whole_bitcoin: T) -> SignedAmount {
|
||||||
SignedAmount::from_int_btc_const(whole_bitcoin.into())
|
SignedAmount::from_int_btc_const(whole_bitcoin.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`]
|
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`]
|
||||||
/// in const context.
|
/// in const context.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// If `whole_bitcoin` is greater than `21_000_000`.
|
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub const fn from_int_btc_const(whole_bitcoin: i32) -> Result<SignedAmount, OutOfRangeError> {
|
pub const fn from_int_btc_const(whole_bitcoin: i16) -> SignedAmount {
|
||||||
let btc = whole_bitcoin as i64; // Can't call `into` in const context.
|
let btc = whole_bitcoin as i64; // Can't call `into` in const context.
|
||||||
match btc.checked_mul(100_000_000) {
|
let sats = btc * 100_000_000;
|
||||||
Some(amount) => SignedAmount::from_sat(amount),
|
|
||||||
None => panic!("cannot overflow in i64"),
|
match SignedAmount::from_sat(sats) {
|
||||||
|
Ok(amount) => amount,
|
||||||
|
Err(_) => panic!("unreachable - 65536 BTC is within range"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn from_str_zero_without_denomination() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_int_btc() {
|
fn from_int_btc() {
|
||||||
let amt = Amount::from_int_btc_const(2).unwrap();
|
let amt = Amount::from_int_btc_const(2);
|
||||||
assert_eq!(sat(200_000_000), amt);
|
assert_eq!(sat(200_000_000), amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,9 +75,9 @@ impl Amount {
|
||||||
/// Exactly one satoshi.
|
/// Exactly one satoshi.
|
||||||
pub const ONE_SAT: Self = Amount::from_sat_unchecked(1);
|
pub const ONE_SAT: Self = Amount::from_sat_unchecked(1);
|
||||||
/// Exactly one bitcoin.
|
/// Exactly one bitcoin.
|
||||||
pub const ONE_BTC: Self = Amount::from_sat_unchecked(100_000_000);
|
pub const ONE_BTC: Self = Amount::from_int_btc_const(1);
|
||||||
/// Exactly fifty bitcoin.
|
/// Exactly fifty bitcoin.
|
||||||
pub const FIFTY_BTC: Self = Amount::from_sat_unchecked(50 * 100_000_000);
|
pub const FIFTY_BTC: Self = Amount::from_int_btc_const(50);
|
||||||
/// The maximum value allowed as an amount. Useful for sanity checking.
|
/// 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);
|
pub const MAX_MONEY: Self = Amount::from_sat_unchecked(21_000_000 * 100_000_000);
|
||||||
/// The minimum value of an amount.
|
/// The minimum value of an amount.
|
||||||
|
@ -132,27 +132,21 @@ impl Amount {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`].
|
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`].
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// If `whole_bitcoin` is greater than `21_000_000`.
|
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub fn from_int_btc<T: Into<u32>>(whole_bitcoin: T) -> Result<Amount, OutOfRangeError> {
|
pub fn from_int_btc<T: Into<u16>>(whole_bitcoin: T) -> Amount {
|
||||||
Amount::from_int_btc_const(whole_bitcoin.into())
|
Amount::from_int_btc_const(whole_bitcoin.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`]
|
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`]
|
||||||
/// in const context.
|
/// in const context.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// If `whole_bitcoin` is greater than `21_000_000`.
|
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub const fn from_int_btc_const(whole_bitcoin: u32) -> Result<Amount, OutOfRangeError> {
|
pub const fn from_int_btc_const(whole_bitcoin: u16) -> Amount {
|
||||||
let btc = whole_bitcoin as u64; // Can't call `into` in const context.
|
let btc = whole_bitcoin as u64; // Can't call `into` in const context.
|
||||||
match btc.checked_mul(100_000_000) {
|
let sats = btc * 100_000_000;
|
||||||
Some(amount) => Amount::from_sat(amount),
|
|
||||||
None => panic!("cannot overflow a u64"),
|
match Amount::from_sat(sats) {
|
||||||
|
Ok(amount) => amount,
|
||||||
|
Err(_) => panic!("unreachable - 65536 BTC is within range"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue