Merge rust-bitcoin/rust-bitcoin#3786: units::SignedAmount make rustdocs conform to the API guidelines

937a3da8dd Add rustdoc errors (Jamil Lambert, PhD)
78f1628bf6 Add Examples to rustdocs (Jamil Lambert, PhD)
09e184015e Fix rustdocs in SignedAmount (Jamil Lambert, PhD)

Pull request description:

  Update rustdocs in `units::SignedAmount` to conform to the API guidelines.  Add examples to `Amount` to match the ones added to `SignedAmount`.

ACKs for top commit:
  tcharding:
    ACK 937a3da8dd
  apoelstra:
    ACK 937a3da8dde74128f79486cf2668f9abaf133bea; successfully ran local tests

Tree-SHA512: a7ad926a33d0943d7334cf3990392d9ca5911603c5ddda69601dd2f744ff0784bd123317179c88d9841c3e9f25f9d75e745100c5b4db7a5b801a7d6a5e15f948
This commit is contained in:
merge-script 2024-12-20 03:52:05 +00:00
commit 229aa0141a
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 145 additions and 27 deletions

View File

@ -19,15 +19,15 @@ use super::{
/// A signed amount.
///
/// The [`SignedAmount`] type can be used to express Bitcoin amounts that support arithmetic and
/// conversion to various denominations. The `Amount` type does not implement `serde` traits but we
/// do provide modules for serializing as satoshis or bitcoin.
/// conversion to various denominations. The [`SignedAmount`] type does not implement [`serde`]
/// traits but we do provide modules for serializing as satoshis or bitcoin.
///
/// Warning!
///
/// This type implements several arithmetic operations from [`core::ops`].
/// To prevent errors due to overflow or underflow when using these operations,
/// it is advised to instead use the checked arithmetic methods whose names
/// start with `checked_`. The operations from [`core::ops`] that [`Amount`]
/// start with `checked_`. The operations from [`core::ops`] that [`SignedAmount`]
/// implements will panic when overflow or underflow occurs.
///
/// # Examples
@ -63,12 +63,41 @@ impl SignedAmount {
pub const MAX: Self = SignedAmount::MAX_MONEY;
/// Constructs a new [`SignedAmount`] with satoshi precision and the given number of satoshis.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::SignedAmount;
/// let amount = SignedAmount::from_sat(-100_000);
/// assert_eq!(amount.to_sat(), -100_000);
/// ```
pub const fn from_sat(satoshi: i64) -> SignedAmount { SignedAmount(satoshi) }
/// Gets the number of satoshis in this [`SignedAmount`].
///
/// # Examples
///
/// ```
/// # use bitcoin_units::SignedAmount;
/// assert_eq!(SignedAmount::ONE_BTC.to_sat(), 100_000_000);
/// ```
pub const fn to_sat(self) -> i64 { self.0 }
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`].
/// Converts from a value expressing a decimal number of bitcoin to a [`SignedAmount`].
///
/// # Errors
///
/// If the amount is too big (positive or negative) or too precise.
///
/// Please be aware of the risk of using floating-point numbers.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::SignedAmount;
/// let amount = SignedAmount::from_btc(-0.01).expect("we know 0.01 is valid");
/// assert_eq!(amount.to_sat(), -1_000_000);
/// ```
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<SignedAmount, ParseAmountError> {
SignedAmount::from_float_in(btc, Denomination::Bitcoin)
@ -101,10 +130,14 @@ impl SignedAmount {
}
}
/// Parses a decimal string as a value in the given denomination.
/// Parses a decimal string as a value in the given [`Denomination`].
///
/// Note: This only parses the value string. If you want to parse a value
/// with denomination, use [`FromStr`].
/// Note: This only parses the value string. If you want to parse a string
/// containing the value with denomination, use [`FromStr`].
///
/// # Errors
///
/// If the amount is too big (positive or negative) or too precise.
pub fn from_str_in(s: &str, denom: Denomination) -> Result<SignedAmount, ParseAmountError> {
match parse_signed_to_satoshi(s, denom).map_err(|error| error.convert(true))? {
// (negative, amount)
@ -123,20 +156,41 @@ impl SignedAmount {
/// or with [`fmt::Display`].
///
/// If you want to parse only the amount without the denomination, use [`Self::from_str_in`].
///
/// # Errors
///
/// If the amount is too big (positive or negative) or too precise.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::{amount, SignedAmount};
/// let amount = SignedAmount::from_str_with_denomination("0.1 BTC")?;
/// assert_eq!(amount, SignedAmount::from_sat(10_000_000));
/// # Ok::<_, amount::ParseError>(())
/// ```
pub fn from_str_with_denomination(s: &str) -> Result<SignedAmount, ParseError> {
let (amt, denom) = split_amount_and_denomination(s)?;
SignedAmount::from_str_in(amt, denom).map_err(Into::into)
}
/// Express this [`SignedAmount`] as a floating-point value in the given denomination.
/// Expresses this [`SignedAmount`] as a floating-point value in the given [`Denomination`].
///
/// Please be aware of the risk of using floating-point numbers.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::amount::{SignedAmount, Denomination};
/// let amount = SignedAmount::from_sat(100_000);
/// assert_eq!(amount.to_float_in(Denomination::Bitcoin), 0.001)
/// ```
#[cfg(feature = "alloc")]
pub fn to_float_in(self, denom: Denomination) -> f64 {
self.to_string_in(denom).parse::<f64>().unwrap()
}
/// Express this [`SignedAmount`] as a floating-point value in Bitcoin.
/// Expresses this [`SignedAmount`] as a floating-point value in Bitcoin.
///
/// Please be aware of the risk of using floating-point numbers.
///
@ -150,12 +204,11 @@ impl SignedAmount {
#[cfg(feature = "alloc")]
pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) }
/// Convert this [`SignedAmount`] in floating-point notation with a given
/// denomination.
/// Converts this [`SignedAmount`] in floating-point notation in the given [`Denomination`].
///
/// # Errors
///
/// If the amount is too big, too precise or negative.
/// If the amount is too big (positive or negative) or too precise.
///
/// Please be aware of the risk of using floating-point numbers.
#[cfg(feature = "alloc")]
@ -168,7 +221,21 @@ impl SignedAmount {
SignedAmount::from_str_in(&value.to_string(), denom)
}
/// Constructs a new object that implements [`fmt::Display`] using specified denomination.
/// Constructs a new object that implements [`fmt::Display`] in the given [`Denomination`].
///
/// This function is useful if you do not wish to allocate. See also [`Self::to_string_in`].
///
/// # Examples
///
/// ```
/// # use bitcoin_units::amount::{SignedAmount, Denomination};
/// # use std::fmt::Write;
/// let amount = SignedAmount::from_sat(10_000_000);
/// let mut output = String::new();
/// write!(&mut output, "{}", amount.display_in(Denomination::Bitcoin))?;
/// assert_eq!(output, "0.1");
/// # Ok::<(), std::fmt::Error>(())
/// ```
#[must_use]
pub fn display_in(self, denomination: Denomination) -> Display {
Display {
@ -178,7 +245,8 @@ impl SignedAmount {
}
}
/// Constructs a new object that implements [`fmt::Display`] dynamically selecting denomination.
/// Constructs a new object that implements [`fmt::Display`] dynamically selecting
/// [`Denomination`].
///
/// This will use BTC for values greater than or equal to 1 BTC and satoshis otherwise. To
/// avoid confusion the denomination is always shown.
@ -191,14 +259,30 @@ impl SignedAmount {
}
}
/// Returns a formatted string representing this [`SignedAmount`] in the given denomination.
/// Returns a formatted string representing this [`SignedAmount`] in the given [`Denomination`].
///
/// Does not include the denomination.
/// Returned string does not include the denomination.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::amount::{SignedAmount, Denomination};
/// let amount = SignedAmount::from_sat(10_000_000);
/// assert_eq!(amount.to_string_in(Denomination::Bitcoin), "0.1")
/// ```
#[cfg(feature = "alloc")]
pub fn to_string_in(self, denom: Denomination) -> String { self.display_in(denom).to_string() }
/// Returns a formatted string representing this [`Amount`] in the given denomination, suffixed
/// with the abbreviation for the denomination.
/// Returns a formatted string representing this [`SignedAmount`] in the given [`Denomination`],
/// suffixed with the abbreviation for the denomination.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::amount::{SignedAmount, Denomination};
/// let amount = SignedAmount::from_sat(10_000_000);
/// assert_eq!(amount.to_string_with_denomination(Denomination::Bitcoin), "0.1 BTC")
/// ```
#[cfg(feature = "alloc")]
pub fn to_string_with_denomination(self, denom: Denomination) -> String {
self.display_in(denom).show_denomination().to_string()
@ -206,7 +290,7 @@ impl SignedAmount {
// Some arithmetic that doesn't fit in [`core::ops`] traits.
/// Get the absolute value of this [`SignedAmount`].
/// Gets the absolute value of this [`SignedAmount`].
#[must_use]
pub fn abs(self) -> SignedAmount { SignedAmount(self.0.abs()) }
@ -238,7 +322,7 @@ impl SignedAmount {
///
/// Consider using `unsigned_abs` which is often more practical.
///
/// Returns [`None`] if overflow occurred. (`self == MIN`)
/// Returns [`None`] if overflow occurred. (`self == i64::MIN`)
#[must_use]
pub const fn checked_abs(self) -> Option<SignedAmount> {
// No `map()` in const context.
@ -250,7 +334,7 @@ impl SignedAmount {
/// Checked addition.
///
/// Returns [`None`] if overflow occurred.
/// Returns [`None`] if the sum is above [`SignedAmount::MAX`] or below [`SignedAmount::MIN`].
#[must_use]
pub const fn checked_add(self, rhs: SignedAmount) -> Option<SignedAmount> {
// No `map()` in const context.
@ -262,7 +346,8 @@ impl SignedAmount {
/// Checked subtraction.
///
/// Returns [`None`] if overflow occurred.
/// Returns [`None`] if the difference is above [`SignedAmount::MAX`] or below
/// [`SignedAmount::MIN`].
#[must_use]
pub const fn checked_sub(self, rhs: SignedAmount) -> Option<SignedAmount> {
// No `map()` in const context.
@ -274,7 +359,8 @@ impl SignedAmount {
/// Checked multiplication.
///
/// Returns [`None`] if overflow occurred.
/// Returns [`None`] if the product is above [`SignedAmount::MAX`] or below
/// [`SignedAmount::MIN`].
#[must_use]
pub const fn checked_mul(self, rhs: i64) -> Option<SignedAmount> {
// No `map()` in const context.
@ -345,6 +431,10 @@ impl SignedAmount {
}
/// Converts to an unsigned amount.
///
/// # Errors
///
/// If the amount is negative.
pub fn to_unsigned(self) -> Result<Amount, OutOfRangeError> {
if self.is_negative() {
Err(OutOfRangeError::negative())

View File

@ -81,6 +81,13 @@ impl Amount {
pub const fn from_sat(satoshi: u64) -> Amount { Amount(satoshi) }
/// Gets the number of satoshis in this [`Amount`].
///
/// # Examples
///
/// ```
/// # use bitcoin_units::Amount;
/// assert_eq!(Amount::ONE_BTC.to_sat(), 100_000_000);
/// ```
pub const fn to_sat(self) -> u64 { self.0 }
/// Converts from a value expressing a decimal number of bitcoin to an [`Amount`].
@ -90,6 +97,14 @@ impl Amount {
/// If the amount is too big, too precise or negative.
///
/// Please be aware of the risk of using floating-point numbers.
///
/// # Examples
///
/// ```
/// # use bitcoin_units::Amount;
/// let amount = Amount::from_btc(0.01).expect("we know 0.01 is valid");
/// assert_eq!(amount.to_sat(), 1_000_000);
/// ```
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<Amount, ParseAmountError> {
Amount::from_float_in(btc, Denomination::Bitcoin)
@ -199,8 +214,7 @@ impl Amount {
#[cfg(feature = "alloc")]
pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) }
/// Converts this [`Amount`] in floating-point notation in the given
/// [`Denomination`].
/// Converts this [`Amount`] in floating-point notation in the given [`Denomination`].
///
/// # Errors
///
@ -218,6 +232,20 @@ impl Amount {
}
/// Constructs a new object that implements [`fmt::Display`] in the given [`Denomination`].
///
/// This function is useful if you do not wish to allocate. See also [`Self::to_string_in`].
///
/// # Examples
///
/// ```
/// # use bitcoin_units::amount::{Amount, Denomination};
/// # use std::fmt::Write;
/// let amount = Amount::from_sat(10_000_000);
/// let mut output = String::new();
/// write!(&mut output, "{}", amount.display_in(Denomination::Bitcoin))?;
/// assert_eq!(output, "0.1");
/// # Ok::<(), std::fmt::Error>(())
/// ```
#[must_use]
pub fn display_in(self, denomination: Denomination) -> Display {
Display {
@ -326,7 +354,7 @@ impl Amount {
///
/// Be aware that integer division loses the remainder if no exact division
/// can be made. This method rounds up ensuring the transaction fee-rate is
/// sufficient. See also [`Amount::checked_div_by_weight_floor`].
/// sufficient. See also [`Self::checked_div_by_weight_floor`].
///
/// Returns [`None`] if overflow occurred.
///
@ -359,7 +387,7 @@ impl Amount {
/// Checked weight floor division.
///
/// Be aware that integer division loses the remainder if no exact division
/// can be made. See also [`Amount::checked_div_by_weight_ceil`].
/// can be made. See also [`Self::checked_div_by_weight_ceil`].
///
/// Returns [`None`] if overflow occurred.
#[cfg(feature = "alloc")]