Merge rust-bitcoin/rust-bitcoin#2957: Fix rustdocs in `units` crate

6dd5af9678 Add missing links (Jamil Lambert, PhD)
47e367f011 Standardize error headings (Jamil Lambert, PhD)
75f317a689 Fix rustdoc grammar (Jamil Lambert, PhD)
573f8ce724 Add backticks to rustdoc links (Jamil Lambert, PhD)

Pull request description:

  The rustdocs in the `units` crate has been reviewed and improved.

  Some of the links were missing backticks, these have been added.

  Some grammatical changes have been made to improve the documentation.

  The use of links was inconsistent and has been changed to have links everywhere that seemed appropriate.

  A couple of error headings were added and a description as to why a capital M is not accepted in the denomination for MegaSatoshi or MegaBitcoin.

ACKs for top commit:
  apoelstra:
    ACK 6dd5af9678
  tcharding:
    ACK 6dd5af9678

Tree-SHA512: f5481a7c3aa99d7882cda9ccda9df9e27f092ff91ef584f07dc887f38bfe12e5ea801cfa7f42bb4022301860489ee6be55557752a8cbe70932f258ea753495dc
This commit is contained in:
merge-script 2024-07-09 14:13:32 +00:00
commit 13e27acb16
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
7 changed files with 180 additions and 149 deletions

View File

@ -2,7 +2,7 @@
//! Bitcoin amounts.
//!
//! This module mainly introduces the [Amount] and [SignedAmount] types.
//! This module mainly introduces the [`Amount`] and [`SignedAmount`] types.
//! We refer to the documentation on the types for more information.
#[cfg(feature = "alloc")]
@ -18,6 +18,19 @@ use internals::write_err;
/// A set of denominations in which amounts can be expressed.
///
/// # Accepted Denominations
///
/// All upper or lower case, excluding SI prefix (c, m, u) which must be lower case.
/// - Singular: BTC, cBTC, mBTC, uBTC
/// - Plural or singular: sat, satoshi, bit
///
/// # Note
///
/// Due to ambiguity between mega and milli we prohibit usage of leading capital 'M'. It is
/// more important to protect users from incorrectly using a capital M to mean milli than to
/// allow Megabitcoin which is not a realistic denomination, and Megasatoshi which is
/// equivalent to cBTC which is allowed.
///
/// # Examples
///
/// ```
@ -67,7 +80,7 @@ impl Denomination {
}
}
/// Returns stringly representation of this
/// Returns a string representation of this denomination.
fn as_str(self) -> &'static str {
match self {
Denomination::Bitcoin => "BTC",
@ -79,7 +92,7 @@ impl Denomination {
}
}
/// The different str forms of denominations that are recognized.
/// The different `str` forms of denominations that are recognized.
fn forms(s: &str) -> Option<Self> {
match s {
"BTC" | "btc" => Some(Denomination::Bitcoin),
@ -105,15 +118,14 @@ impl fmt::Display for Denomination {
impl FromStr for Denomination {
type Err = ParseDenominationError;
/// Convert from a str to Denomination.
/// Converts from a `str` to a `Denomination`.
///
/// # Accepted Denominations
/// # Errors
///
/// All upper or lower case, excluding SI prefix (c, m, u) which must be lower case.
/// - Singular: BTC, cBTC, mBTC, uBTC
/// - Plural or singular: sat, satoshi, bit
/// - If the denomination begins with a capital `M` a [`PossiblyConfusingDenominationError`] is
/// returned.
///
/// Due to ambiguity between mega and milli we prohibit usage of leading capital 'M'.
/// - If an unknown denomination is used, an [`UnknownDenominationError`] is returned.
fn from_str(s: &str) -> Result<Self, Self::Err> {
use self::ParseDenominationError::*;
@ -260,7 +272,7 @@ impl std::error::Error for ParseAmountError {
}
}
/// Returned when a parsed amount is too big or too small.
/// Error returned when a parsed amount is too big or too small.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct OutOfRangeError {
is_signed: bool,
@ -395,7 +407,7 @@ enum MissingDigitsKind {
OnlyMinusSign,
}
/// Returned when the input contains an invalid character.
/// Error returned when the input contains an invalid character.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidCharacterError {
invalid_char: char,
@ -458,7 +470,7 @@ impl std::error::Error for ParseDenominationError {
#[non_exhaustive]
pub struct MissingDenominationError;
/// Parsing error, unknown denomination.
/// Error returned when parsing an unknown denomination.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct UnknownDenominationError(InputString);
@ -474,7 +486,7 @@ impl std::error::Error for UnknownDenominationError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
/// Parsing error, possibly confusing denomination.
/// Error returned when parsing a possibly confusing denomination.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct PossiblyConfusingDenominationError(InputString);
@ -512,8 +524,8 @@ fn is_too_precise(s: &str, precision: usize) -> Option<usize> {
const INPUT_STRING_LEN_LIMIT: usize = 50;
/// Parse decimal string in the given denomination into a satoshi value and a
/// bool indicator for a negative amount.
/// Parses a decimal string in the given denomination into a satoshi value and a
/// [`bool`] indicator for a negative amount.
fn parse_signed_to_satoshi(
mut s: &str,
denom: Denomination,
@ -832,16 +844,16 @@ fn fmt_satoshi_in(
/// An amount.
///
/// The [Amount] type can be used to express Bitcoin amounts that support
/// The [`Amount`] type can be used to express Bitcoin amounts that support
/// arithmetic and conversion to various denominations.
///
///
/// Warning!
///
/// This type implements several arithmetic operations from [core::ops].
/// 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 [`Amount`]
/// implements will panic when overflow or underflow occurs. Also note that
/// since the internal representation of amounts is unsigned, subtracting below
/// zero is considered an underflow and will cause a panic if you're not using
@ -867,19 +879,19 @@ impl Amount {
/// The number of bytes that an amount contributes to the size of a transaction.
pub const SIZE: usize = 8; // Serialized length of a u64.
/// Create an [Amount] with satoshi precision and the given number of satoshis.
/// Creates an [`Amount`] with satoshi precision and the given number of satoshis.
pub const fn from_sat(satoshi: u64) -> Amount { Amount(satoshi) }
/// Gets the number of satoshis in this [`Amount`].
pub fn to_sat(self) -> u64 { self.0 }
/// Convert from a value expressing bitcoins to an [Amount].
/// Converts from a value expressing bitcoins to an [`Amount`].
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<Amount, ParseAmountError> {
Amount::from_float_in(btc, Denomination::Bitcoin)
}
/// Convert from a value expressing integer values of bitcoins to an [Amount]
/// Converts from a value expressing integer values of bitcoins to an [`Amount`]
/// in const context.
///
/// # Panics
@ -900,10 +912,10 @@ impl Amount {
}
}
/// Parse 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].
/// with denomination, use [`FromStr`].
pub fn from_str_in(s: &str, denom: Denomination) -> Result<Amount, ParseAmountError> {
let (negative, satoshi) =
parse_signed_to_satoshi(s, denom).map_err(|error| error.convert(false))?;
@ -914,15 +926,15 @@ impl Amount {
}
/// Parses amounts with denomination suffix like they are produced with
/// [Self::to_string_with_denomination] or with [fmt::Display].
/// [`Self::to_string_with_denomination`] or with [`fmt::Display`].
/// If you want to parse only the amount without the denomination,
/// use [Self::from_str_in].
/// use [`Self::from_str_in`].
pub fn from_str_with_denomination(s: &str) -> Result<Amount, ParseError> {
let (amt, denom) = split_amount_and_denomination(s)?;
Amount::from_str_in(amt, denom).map_err(Into::into)
}
/// Express this [Amount] as a floating-point value in the given denomination.
/// Expresses this [`Amount`] as a floating-point value in the given denomination.
///
/// Please be aware of the risk of using floating-point numbers.
#[cfg(feature = "alloc")]
@ -930,7 +942,7 @@ impl Amount {
f64::from_str(&self.to_string_in(denom)).unwrap()
}
/// Express this [`Amount`] as a floating-point value in Bitcoin.
/// Expresses this [`Amount`] as a floating-point value in Bitcoin.
///
/// Please be aware of the risk of using floating-point numbers.
///
@ -944,9 +956,12 @@ impl Amount {
#[cfg(feature = "alloc")]
pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) }
/// Convert this [Amount] in floating-point notation with a given
/// Converts this [`Amount`] in floating-point notation with a given
/// denomination.
/// Can return error if the amount is too big, too precise or negative.
///
/// # Errors
///
/// If the amount is too big, too precise or negative.
///
/// Please be aware of the risk of using floating-point numbers.
#[cfg(feature = "alloc")]
@ -959,7 +974,7 @@ impl Amount {
Amount::from_str_in(&value.to_string(), denom)
}
/// Create an object that implements [`fmt::Display`] using specified denomination.
/// Creates an object that implements [`fmt::Display`] using specified denomination.
pub fn display_in(self, denomination: Denomination) -> Display {
Display {
sats_abs: self.to_sat(),
@ -968,7 +983,7 @@ impl Amount {
}
}
/// Create an object that implements [`fmt::Display`] dynamically selecting denomination.
/// Creates an 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.
@ -980,7 +995,7 @@ impl Amount {
}
}
/// Format the value of this [Amount] in the given denomination.
/// Formats the value of this [`Amount`] in the given denomination.
///
/// Does not include the denomination.
#[rustfmt::skip]
@ -989,50 +1004,50 @@ impl Amount {
fmt_satoshi_in(self.to_sat(), false, f, denom, false, FormatOptions::default())
}
/// Get a string number of this [Amount] in the given denomination.
/// Returns a formatted string of this [`Amount`] in the given denomination.
///
/// Does not include the denomination.
#[cfg(feature = "alloc")]
pub fn to_string_in(self, denom: Denomination) -> String { self.display_in(denom).to_string() }
/// Get a formatted string of this [Amount] in the given denomination,
/// Returns a formatted string of this [`Amount`] in the given denomination,
/// suffixed with the abbreviation for the denomination.
#[cfg(feature = "alloc")]
pub fn to_string_with_denomination(self, denom: Denomination) -> String {
self.display_in(denom).show_denomination().to_string()
}
// Some arithmetic that doesn't fit in `core::ops` traits.
// Some arithmetic that doesn't fit in [`core::ops`] traits.
/// Checked addition.
///
/// Returns [None] if overflow occurred.
/// Returns [`None`] if overflow occurred.
pub fn checked_add(self, rhs: Amount) -> Option<Amount> {
self.0.checked_add(rhs.0).map(Amount)
}
/// Checked subtraction.
///
/// Returns [None] if overflow occurred.
/// Returns [`None`] if overflow occurred.
pub fn checked_sub(self, rhs: Amount) -> Option<Amount> {
self.0.checked_sub(rhs.0).map(Amount)
}
/// Checked multiplication.
///
/// Returns [None] if overflow occurred.
/// Returns [`None`] if overflow occurred.
pub fn checked_mul(self, rhs: u64) -> Option<Amount> { self.0.checked_mul(rhs).map(Amount) }
/// Checked integer division.
///
/// Be aware that integer division loses the remainder if no exact division
/// can be made.
/// Returns [None] if overflow occurred.
/// Returns [`None`] if overflow occurred.
pub fn checked_div(self, rhs: u64) -> Option<Amount> { self.0.checked_div(rhs).map(Amount) }
/// Checked remainder.
///
/// Returns [None] if overflow occurred.
/// Returns [`None`] if overflow occurred.
pub fn checked_rem(self, rhs: u64) -> Option<Amount> { self.0.checked_rem(rhs).map(Amount) }
/// Unchecked addition.
@ -1053,7 +1068,7 @@ impl Amount {
/// On overflow, panics in debug mode, wraps in release mode.
pub fn unchecked_sub(self, rhs: Amount) -> Amount { Self(self.0 - rhs.0) }
/// Convert to a signed amount.
/// Converts to a signed amount.
pub fn to_signed(self) -> Result<SignedAmount, OutOfRangeError> {
if self.to_sat() > SignedAmount::MAX.to_sat() as u64 {
Err(OutOfRangeError::too_big(true))
@ -1158,13 +1173,13 @@ impl core::iter::Sum for Amount {
/// A helper/builder that displays amount with specified settings.
///
/// This provides richer interface than `fmt::Formatter`:
/// This provides richer interface than [`fmt::Formatter`]:
///
/// * Ability to select denomination
/// * Show or hide denomination
/// * Dynamically-selected denomination - show in sats if less than 1 BTC.
///
/// However this can still be combined with `fmt::Formatter` options to precisely control zeros,
/// However this can still be combined with [`fmt::Formatter`] options to precisely control zeros,
/// padding, alignment... The formatting works like floats from `core` but note that precision will
/// **never** be lossy - that means no rounding.
///
@ -1217,16 +1232,16 @@ enum DisplayStyle {
/// A signed amount.
///
/// The [SignedAmount] type can be used to express Bitcoin amounts that support
/// The [`SignedAmount`] type can be used to express Bitcoin amounts that support
/// arithmetic and conversion to various denominations.
///
///
/// Warning!
///
/// This type implements several arithmetic operations from [core::ops].
/// 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 [`Amount`]
/// implements will panic when overflow or underflow occurs.
///
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -1246,13 +1261,13 @@ impl SignedAmount {
/// The maximum value of an amount.
pub const MAX: SignedAmount = SignedAmount(i64::MAX);
/// Create an [SignedAmount] with satoshi precision and the given number of satoshis.
/// Create an [`SignedAmount`] with satoshi precision and the given number of satoshis.
pub const fn from_sat(satoshi: i64) -> SignedAmount { SignedAmount(satoshi) }
/// Gets the number of satoshis in this [`SignedAmount`].
pub fn to_sat(self) -> i64 { self.0 }
/// Convert from a value expressing bitcoins to an [SignedAmount].
/// Convert from a value expressing bitcoins to an [`SignedAmount`].
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<SignedAmount, ParseAmountError> {
SignedAmount::from_float_in(btc, Denomination::Bitcoin)
@ -1261,7 +1276,7 @@ impl SignedAmount {
/// Parse 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].
/// with denomination, use [`FromStr`].
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)
@ -1276,15 +1291,15 @@ impl SignedAmount {
}
/// Parses amounts with denomination suffix like they are produced with
/// [Self::to_string_with_denomination] or with [fmt::Display].
/// [`Self::to_string_with_denomination`] or with [`fmt::Display`].
/// If you want to parse only the amount without the denomination,
/// use [Self::from_str_in].
/// use [`Self::from_str_in`].
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.
/// Express this [`SignedAmount`] as a floating-point value in the given denomination.
///
/// Please be aware of the risk of using floating-point numbers.
#[cfg(feature = "alloc")]
@ -1300,9 +1315,12 @@ 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
/// Convert this [`SignedAmount`] in floating-point notation with a given
/// denomination.
/// Can return error if the amount is too big, too precise or negative.
///
/// # Errors
///
/// If the amount is too big, too precise or negative.
///
/// Please be aware of the risk of using floating-point numbers.
#[cfg(feature = "alloc")]
@ -1336,7 +1354,7 @@ impl SignedAmount {
}
}
/// Format the value of this [SignedAmount] in the given denomination.
/// Format the value of this [`SignedAmount`] in the given denomination.
///
/// Does not include the denomination.
#[rustfmt::skip]
@ -1345,74 +1363,87 @@ impl SignedAmount {
fmt_satoshi_in(self.unsigned_abs().to_sat(), self.is_negative(), f, denom, false, FormatOptions::default())
}
/// Get a string number of this [SignedAmount] in the given denomination.
/// Get a string number of this [`SignedAmount`] in the given denomination.
///
/// Does not include the denomination.
#[cfg(feature = "alloc")]
pub fn to_string_in(self, denom: Denomination) -> String { self.display_in(denom).to_string() }
/// Get a formatted string of this [SignedAmount] in the given denomination,
/// Get a formatted string of this [`SignedAmount`] in the given denomination,
/// suffixed with the abbreviation for the denomination.
#[cfg(feature = "alloc")]
pub fn to_string_with_denomination(self, denom: Denomination) -> String {
self.display_in(denom).show_denomination().to_string()
}
// Some arithmetic that doesn't fit in `core::ops` traits.
// Some arithmetic that doesn't fit in [`core::ops`] traits.
/// Get the absolute value of this [SignedAmount].
/// Get the absolute value of this [`SignedAmount`].
pub fn abs(self) -> SignedAmount { SignedAmount(self.0.abs()) }
/// Get the absolute value of this [SignedAmount] returning `Amount`.
/// Get the absolute value of this [`SignedAmount`] returning [`Amount`].
pub fn unsigned_abs(self) -> Amount { Amount(self.0.unsigned_abs()) }
/// Returns a number representing sign of this [SignedAmount].
/// Returns a number representing sign of this [`SignedAmount`].
///
/// - `0` if the amount is zero
/// - `1` if the amount is positive
/// - `-1` if the amount is negative
pub fn signum(self) -> i64 { self.0.signum() }
/// Returns `true` if this [SignedAmount] is positive and `false` if
/// this [SignedAmount] is zero or negative.
/// Checks if this [`SignedAmount`] is positive.
///
/// Returns `true` if this [`SignedAmount`] is positive and `false` if
/// this [`SignedAmount`] is zero or negative.
pub fn is_positive(self) -> bool { self.0.is_positive() }
/// Returns `true` if this [SignedAmount] is negative and `false` if
/// this [SignedAmount] is zero or positive.
/// Checks if this [`SignedAmount`] is negative.
///
/// Returns `true` if this [`SignedAmount`] is negative and `false` if
/// this [`SignedAmount`] is zero or positive.
pub fn is_negative(self) -> bool { self.0.is_negative() }
/// Get the absolute value of this [SignedAmount].
/// Returns [None] if overflow occurred. (`self == MIN`)
/// Returns the absolute value of this [`SignedAmount`].
///
/// Consider using `unsigned_abs` which is often more practical.
///
/// Returns [`None`] if overflow occurred. (`self == MIN`)
pub fn checked_abs(self) -> Option<SignedAmount> { self.0.checked_abs().map(SignedAmount) }
/// Checked addition.
/// Returns [None] if overflow occurred.
///
/// Returns [`None`] if overflow occurred.
pub fn checked_add(self, rhs: SignedAmount) -> Option<SignedAmount> {
self.0.checked_add(rhs.0).map(SignedAmount)
}
/// Checked subtraction.
/// Returns [None] if overflow occurred.
///
/// Returns [`None`] if overflow occurred.
pub fn checked_sub(self, rhs: SignedAmount) -> Option<SignedAmount> {
self.0.checked_sub(rhs.0).map(SignedAmount)
}
/// Checked multiplication.
/// Returns [None] if overflow occurred.
///
/// Returns [`None`] if overflow occurred.
pub fn checked_mul(self, rhs: i64) -> Option<SignedAmount> {
self.0.checked_mul(rhs).map(SignedAmount)
}
/// Checked integer division.
///
/// Be aware that integer division loses the remainder if no exact division
/// can be made.
/// Returns [None] if overflow occurred.
///
/// Returns [`None`] if overflow occurred.
pub fn checked_div(self, rhs: i64) -> Option<SignedAmount> {
self.0.checked_div(rhs).map(SignedAmount)
}
/// Checked remainder.
/// Returns [None] if overflow occurred.
///
/// Returns [`None`] if overflow occurred.
pub fn checked_rem(self, rhs: i64) -> Option<SignedAmount> {
self.0.checked_rem(rhs).map(SignedAmount)
}
@ -1435,8 +1466,9 @@ impl SignedAmount {
/// On overflow, panics in debug mode, wraps in release mode.
pub fn unchecked_sub(self, rhs: SignedAmount) -> SignedAmount { Self(self.0 - rhs.0) }
/// Subtraction that doesn't allow negative [SignedAmount]s.
/// Returns [None] if either [self], `rhs` or the result is strictly negative.
/// Subtraction that doesn't allow negative [`SignedAmount`]s.
///
/// Returns [`None`] if either [`self`], `rhs` or the result is strictly negative.
pub fn positive_sub(self, rhs: SignedAmount) -> Option<SignedAmount> {
if self.is_negative() || rhs.is_negative() || rhs > self {
None
@ -1445,7 +1477,7 @@ impl SignedAmount {
}
}
/// Convert to an unsigned amount.
/// Converts to an unsigned amount.
pub fn to_unsigned(self) -> Result<Amount, OutOfRangeError> {
if self.is_negative() {
Err(OutOfRangeError::negative())
@ -1558,10 +1590,10 @@ impl core::iter::Sum for SignedAmount {
}
}
/// Calculate the sum over the iterator using checked arithmetic.
/// Calculates the sum over the iterator using checked arithmetic.
pub trait CheckedSum<R>: private::SumSeal<R> {
/// Calculate the sum over the iterator using checked arithmetic. If an over or underflow would
/// happen it returns `None`.
/// Calculates the sum over the iterator using checked arithmetic. If an over or underflow would
/// happen it returns [`None`].
fn checked_sum(self) -> Option<R>;
}

View File

@ -65,10 +65,10 @@ impl From<BlockHeight> for u32 {
}
impl From<absolute::Height> for BlockHeight {
/// Converts [`locktime::absolute::Height`] to a [`BlockHeight`].
/// Converts a [`locktime::absolute::Height`] to a [`BlockHeight`].
///
/// An absolute locktime block height has a maximum value of `absolute::LOCK_TIME_THRESHOLD`
/// (500,000,000) where as a `BlockHeight` is a thin wrapper around a `u32`, the two types are
/// An absolute locktime block height has a maximum value of [`absolute::LOCK_TIME_THRESHOLD`]
/// (500,000,000) where as a [`BlockHeight`] is a thin wrapper around a `u32`, the two types are
/// not interchangeable.
fn from(h: absolute::Height) -> Self { Self::from_u32(h.to_consensus_u32()) }
}
@ -76,10 +76,10 @@ impl From<absolute::Height> for BlockHeight {
impl TryFrom<BlockHeight> for absolute::Height {
type Error = absolute::ConversionError;
/// Converts [`BlockHeight`] to a [`locktime::absolute::Height`].
/// Converts a [`BlockHeight`] to a [`locktime::absolute::Height`].
///
/// An absolute locktime block height has a maximum value of `absolute::LOCK_TIME_THRESHOLD`
/// (500,000,000) where as a `BlockHeight` is a thin wrapper around a `u32`, the two types are
/// An absolute locktime block height has a maximum value of [`absolute::LOCK_TIME_THRESHOLD`]
/// (500,000,000) where as a [`BlockHeight`] is a thin wrapper around a `u32`, the two types are
/// not interchangeable.
fn try_from(h: BlockHeight) -> Result<Self, Self::Error> {
absolute::Height::from_consensus(h.to_u32())
@ -132,20 +132,20 @@ impl From<BlockInterval> for u32 {
}
impl From<relative::Height> for BlockInterval {
/// Converts [`locktime::relative::Height`] to a [`BlockInterval`].
/// Converts a [`locktime::relative::Height`] to a [`BlockInterval`].
///
/// A relative locktime block height has a maximum value of `u16::MAX` where as a
/// `BlockInterval` is a thin wrapper around a `u32`, the two types are not interchangeable.
/// [`BlockInterval`] is a thin wrapper around a `u32`, the two types are not interchangeable.
fn from(h: relative::Height) -> Self { Self::from_u32(h.value().into()) }
}
impl TryFrom<BlockInterval> for relative::Height {
type Error = TooBigForRelativeBlockHeightError;
/// Converts [`BlockInterval`] to a [`locktime::relative::Height`].
/// Converts a [`BlockInterval`] to a [`locktime::relative::Height`].
///
/// A relative locktime block height has a maximum value of `u16::MAX` where as a
/// `BlockInterval` is a thin wrapper around a `u32`, the two types are not interchangeable.
/// [`BlockInterval`] is a thin wrapper around a `u32`, the two types are not interchangeable.
fn try_from(h: BlockInterval) -> Result<Self, Self::Error> {
let h = h.to_u32();
if h > u16::MAX as u32 {
@ -155,7 +155,7 @@ impl TryFrom<BlockInterval> for relative::Height {
}
}
/// The block interval is too big to be used as a relative lock time.
/// Error returned when the block interval is too big to be used as a relative lock time.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TooBigForRelativeBlockHeightError(u32);

View File

@ -42,14 +42,14 @@ impl FeeRate {
/// Fee rate used to compute dust amount.
pub const DUST: FeeRate = FeeRate::from_sat_per_vb_unchecked(3);
/// Constructs `FeeRate` from satoshis per 1000 weight units.
/// Constructs [`FeeRate`] from satoshis per 1000 weight units.
pub const fn from_sat_per_kwu(sat_kwu: u64) -> Self { FeeRate(sat_kwu) }
/// Constructs `FeeRate` from satoshis per virtual bytes.
/// Constructs [`FeeRate`] from satoshis per virtual bytes.
///
/// # Errors
///
/// Returns `None` on arithmetic overflow.
/// Returns [`None`] on arithmetic overflow.
pub fn from_sat_per_vb(sat_vb: u64) -> Option<Self> {
// 1 vb == 4 wu
// 1 sat/vb == 1/4 sat/wu
@ -57,7 +57,7 @@ impl FeeRate {
Some(FeeRate(sat_vb.checked_mul(1000 / 4)?))
}
/// Constructs `FeeRate` from satoshis per virtual bytes without overflow check.
/// Constructs [`FeeRate`] from satoshis per virtual bytes without overflow check.
pub const fn from_sat_per_vb_unchecked(sat_vb: u64) -> Self { FeeRate(sat_vb * (1000 / 4)) }
/// Returns raw fee rate.
@ -73,34 +73,34 @@ impl FeeRate {
/// Checked multiplication.
///
/// Computes `self * rhs` returning `None` if overflow occurred.
/// Computes `self * rhs` returning [`None`] if overflow occurred.
pub fn checked_mul(self, rhs: u64) -> Option<Self> { self.0.checked_mul(rhs).map(Self) }
/// Checked division.
///
/// Computes `self / rhs` returning `None` if `rhs == 0`.
/// Computes `self / rhs` returning [`None`] if `rhs == 0`.
pub fn checked_div(self, rhs: u64) -> Option<Self> { self.0.checked_div(rhs).map(Self) }
/// Checked weight multiplication.
///
/// Computes the absolute fee amount for a given [`Weight`] at this fee rate.
///
/// `None` is returned if an overflow occurred.
/// [`None`] is returned if an overflow occurred.
pub fn checked_mul_by_weight(self, rhs: Weight) -> Option<Amount> {
let sats = self.0.checked_mul(rhs.to_wu())?.checked_add(999)? / 1000;
Some(Amount::from_sat(sats))
}
/// Calculates fee by multiplying this fee rate by weight, in weight units, returning `None`
/// if overflow occurred.
/// Calculates the fee by multiplying this fee rate by weight, in weight units, returning [`None`]
/// if an overflow occurred.
///
/// This is equivalent to `Self::checked_mul_by_weight()`.
pub fn fee_wu(self, weight: Weight) -> Option<Amount> { self.checked_mul_by_weight(weight) }
/// Calculates fee by multiplying this fee rate by weight, in virtual bytes, returning `None`
/// if overflow occurred.
/// Calculates the fee by multiplying this fee rate by weight, in virtual bytes, returning [`None`]
/// if an overflow occurred.
///
/// This is equivalent to converting `vb` to `weight` using `Weight::from_vb` and then calling
/// This is equivalent to converting `vb` to [`Weight`] using [`Weight::from_vb`] and then calling
/// `Self::fee_wu(weight)`.
pub fn fee_vb(self, vb: u64) -> Option<Amount> {
Weight::from_vb(vb).and_then(|w| self.fee_wu(w))
@ -122,7 +122,7 @@ impl From<FeeRate> for u64 {
fn from(value: FeeRate) -> Self { value.to_sat_per_kwu() }
}
/// Computes ceiling so that fee computation is conservative.
/// Computes the ceiling so that the fee computation is conservative.
impl Mul<FeeRate> for Weight {
type Output = Amount;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: CC0-1.0
//! Provides type `Height` and `Time` types used by the `rust-bitcoin` `absolute::LockTime` type.
//! Provides [`Height`] and [`Time`] types used by the `rust-bitcoin` `absolute::LockTime` type.
use core::fmt;
@ -39,9 +39,9 @@ impl Height {
/// The maximum absolute block height.
pub const MAX: Self = Height(LOCK_TIME_THRESHOLD - 1);
/// Creates a `Height` from a hex string.
/// Creates a [`Height`] from a hex string.
///
/// The input string is may or may not contain a typical hex prefix e.g., `0x`.
/// The input string may or may not contain a typical hex prefix e.g., `0x`.
pub fn from_hex(s: &str) -> Result<Self, ParseHeightError> {
parse_hex(s, Self::from_consensus)
}
@ -70,7 +70,7 @@ impl Height {
}
}
/// Converts this `Height` to its inner `u32` value.
/// Converts this [`Height`] to its inner `u32` value.
#[inline]
pub fn to_consensus_u32(self) -> u32 { self.0 }
}
@ -137,9 +137,9 @@ impl Time {
/// The maximum absolute block time (Sun Feb 07 2106 06:28:15 GMT+0000).
pub const MAX: Self = Time(u32::MAX);
/// Creates a `Time` from a hex string.
/// Creates a [`Time`] from a hex string.
///
/// The input string is may or may not contain a typical hex prefix e.g., `0x`.
/// The input string may or may not contain a typical hex prefix e.g., `0x`.
pub fn from_hex(s: &str) -> Result<Self, ParseTimeError> { parse_hex(s, Self::from_consensus) }
/// Constructs a new block time.
@ -166,7 +166,7 @@ impl Time {
}
}
/// Converts this `Time` to its inner `u32` value.
/// Converts this [`Time`] to its inner `u32` value.
#[inline]
pub fn to_consensus_u32(self) -> u32 { self.0 }
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: CC0-1.0
//! Provides type `Height` and `Time` types used by the `rust-bitcoin` `relative::LockTime` type.
//! Provides [`Height`] and [`Time`] types used by the `rust-bitcoin` `relative::LockTime` type.
use core::fmt;
@ -64,13 +64,13 @@ impl Time {
/// The maximum relative block time (33,554,432 seconds or approx 388 days).
pub const MAX: Self = Time(u16::MAX);
/// Create a [`Time`] using time intervals where each interval is equivalent to 512 seconds.
/// Creates a [`Time`] using time intervals where each interval is equivalent to 512 seconds.
///
/// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin.
#[inline]
pub const fn from_512_second_intervals(intervals: u16) -> Self { Time(intervals) }
/// Create a [`Time`] from seconds, converting the seconds into 512 second interval with
/// Creates a [`Time`] from seconds, converting the seconds into 512 second interval with
/// truncating division.
///
/// # Errors
@ -87,8 +87,8 @@ impl Time {
}
}
/// Create a [`Time`] from seconds, converting the seconds into 512 second interval with ceiling
/// division.
/// Creates a [`Time`] from seconds, converting the seconds into 512 second intervals with
/// ceiling division.
///
/// # Errors
///

View File

@ -160,11 +160,11 @@ macro_rules! impl_parse_str {
}
}
/// Removes the prefix `0x` (or `0X`) from hex string.
/// Removes the prefix `0x` (or `0X`) from a hex string.
///
/// # Errors
///
/// If input string does not contain a prefix.
/// If the input string does not contain a prefix.
pub fn hex_remove_prefix(s: &str) -> Result<&str, PrefixedHexError> {
if let Some(checked) = s.strip_prefix("0x") {
Ok(checked)
@ -175,11 +175,11 @@ pub fn hex_remove_prefix(s: &str) -> Result<&str, PrefixedHexError> {
}
}
/// Checks hex string does not have a prefix `0x` (or `0X`).
/// Checks a hex string does not have a prefix `0x` (or `0X`).
///
/// # Errors
///
/// If input string contains a prefix.
/// If the input string contains a prefix.
pub fn hex_check_unprefixed(s: &str) -> Result<&str, UnprefixedHexError> {
if s.starts_with("0x") || s.starts_with("0X") {
return Err(ContainsPrefixError::new(s.into()).into());
@ -203,8 +203,8 @@ pub fn hex_u32(s: &str) -> Result<u32, ParseIntError> {
///
/// # Errors
///
/// - If input string does not contain a `0x` (or `0X`) prefix.
/// - If input string is not a valid hex encoding of a `u32`.
/// - If the input string does not contain a `0x` (or `0X`) prefix.
/// - If the input string is not a valid hex encoding of a `u32`.
pub fn hex_u32_prefixed(s: &str) -> Result<u32, PrefixedHexError> {
let checked = hex_remove_prefix(s)?;
Ok(hex_u32_unchecked(checked)?)
@ -214,19 +214,19 @@ pub fn hex_u32_prefixed(s: &str) -> Result<u32, PrefixedHexError> {
///
/// # Errors
///
/// - If input string contains a `0x` (or `0X`) prefix.
/// - If input string is not a valid hex encoding of a `u32`.
/// - If the input string contains a `0x` (or `0X`) prefix.
/// - If the input string is not a valid hex encoding of a `u32`.
pub fn hex_u32_unprefixed(s: &str) -> Result<u32, UnprefixedHexError> {
let checked = hex_check_unprefixed(s)?;
Ok(hex_u32_unchecked(checked)?)
}
/// Parses a `u32` from a hex string.
/// Parses a `u32` from an unprefixed hex string without first checking for a prefix.
///
/// # Errors
///
/// - If input string is not a valid hex encoding of a `u32`.
/// - With `InvalidDigit` due to the `x` if there is a prefix.
/// - If the input string contains a `0x` (or `0X`) prefix, returns `InvalidDigit` due to the `x`.
/// - If the input string is not a valid hex encoding of a `u32`.
pub fn hex_u32_unchecked(s: &str) -> Result<u32, ParseIntError> {
u32::from_str_radix(s, 16).map_err(|error| ParseIntError {
input: s.into(),
@ -252,8 +252,8 @@ pub fn hex_u128(s: &str) -> Result<u128, ParseIntError> {
///
/// # Errors
///
/// - If input string does not contain a `0x` (or `0X`) prefix.
/// - If input string is not a valid hex encoding of a `u128`.
/// - If the input string does not contain a `0x` (or `0X`) prefix.
/// - If the input string is not a valid hex encoding of a `u128`.
pub fn hex_u128_prefixed(s: &str) -> Result<u128, PrefixedHexError> {
let checked = hex_remove_prefix(s)?;
Ok(hex_u128_unchecked(checked)?)
@ -263,19 +263,19 @@ pub fn hex_u128_prefixed(s: &str) -> Result<u128, PrefixedHexError> {
///
/// # Errors
///
/// - If input string contains a `0x` (or `0X`) prefix.
/// - If input string is not a valid hex encoding of a `u128`.
/// - If the input string contains a `0x` (or `0X`) prefix.
/// - If the input string is not a valid hex encoding of a `u128`.
pub fn hex_u128_unprefixed(s: &str) -> Result<u128, UnprefixedHexError> {
let checked = hex_check_unprefixed(s)?;
Ok(hex_u128_unchecked(checked)?)
}
/// Parses a `u128` from a hex string.
/// Parses a `u128` from an unprefixed hex string without first checking for a prefix.
///
/// # Errors
///
/// - If input string is not a valid hex encoding of a `u128`.
/// - With `InvalidDigit` due to the `x` if there is a prefix.
/// - If the input string contains a `0x` (or `0X`) prefix, returns `InvalidDigit` due to the `x`.
/// - If the input string is not a valid hex encoding of a `u128`.
pub fn hex_u128_unchecked(s: &str) -> Result<u128, ParseIntError> {
u128::from_str_radix(s, 16).map_err(|error| ParseIntError {
input: s.into(),
@ -296,8 +296,7 @@ pub(crate) fn hex_remove_optional_prefix(s: &str) -> &str {
}
}
/// Error returned when parsing integer from an supposedly prefixed hex string for
/// a type that can be created infallibly from an integer.
/// Error returned when parsing an integer from a hex string that is supposed to contain a prefix.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum PrefixedHexError {
/// Hex string is missing prefix.
@ -337,7 +336,7 @@ impl From<ParseIntError> for PrefixedHexError {
fn from(e: ParseIntError) -> Self { Self::ParseInt(e) }
}
/// Error returned when parsing integer from an supposedly un-prefixed hex string.
/// Error returned when parsing an integer from a hex string that is not supposed to contain a prefix.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum UnprefixedHexError {
/// Hex string contains prefix.
@ -377,7 +376,7 @@ impl From<ParseIntError> for UnprefixedHexError {
fn from(e: ParseIntError) -> Self { Self::ParseInt(e) }
}
/// Error when hex string is missing a prefix (e.g. 0x).
/// Error returned when a hex string is missing a prefix (e.g. `0x`).
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct MissingPrefixError {
hex: String,

View File

@ -13,7 +13,7 @@ pub const WITNESS_SCALE_FACTOR: usize = 4;
/// Represents block weight - the weight of a transaction or block.
///
/// This is an integer newtype representing weigth in `wu`. It provides protection against mixing
/// This is an integer newtype representing [`Weight`] in `wu`. It provides protection against mixing
/// up the types as well as basic formatting features.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -43,21 +43,21 @@ impl Weight {
/// The minimum transaction weight for a valid serialized transaction.
pub const MIN_TRANSACTION: Weight = Weight(Self::WITNESS_SCALE_FACTOR * 60);
/// Directly constructs `Weight` from weight units.
/// Directly constructs [`Weight`] from weight units.
pub const fn from_wu(wu: u64) -> Self { Weight(wu) }
/// Directly constructs `Weight` from usize weight units.
/// Directly constructs [`Weight`] from usize weight units.
pub const fn from_wu_usize(wu: usize) -> Self { Weight(wu as u64) }
/// Constructs `Weight` from kilo weight units returning `None` if an overflow occurred.
/// Constructs [`Weight`] from kilo weight units returning [`None`] if an overflow occurred.
pub fn from_kwu(wu: u64) -> Option<Self> { wu.checked_mul(1000).map(Weight) }
/// Constructs `Weight` from virtual bytes, returning `None` on overflow.
/// Constructs [`Weight`] from virtual bytes, returning [`None`] if an overflow occurred.
pub fn from_vb(vb: u64) -> Option<Self> {
vb.checked_mul(Self::WITNESS_SCALE_FACTOR).map(Weight::from_wu)
}
/// Constructs `Weight` from virtual bytes panicking on overflow.
/// Constructs [`Weight`] from virtual bytes panicking if an overflow occurred.
///
/// # Panics
///
@ -76,13 +76,13 @@ impl Weight {
}
}
/// Constructs `Weight` from virtual bytes without an overflow check.
/// Constructs [`Weight`] from virtual bytes without an overflow check.
pub const fn from_vb_unchecked(vb: u64) -> Self { Weight::from_wu(vb * 4) }
/// Constructs `Weight` from witness size.
/// Constructs [`Weight`] from witness size.
pub const fn from_witness_data_size(witness_size: u64) -> Self { Weight(witness_size) }
/// Constructs `Weight` from non-witness size.
/// Constructs [`Weight`] from non-witness size.
pub const fn from_non_witness_data_size(non_witness_size: u64) -> Self {
Weight(non_witness_size * Self::WITNESS_SCALE_FACTOR)
}
@ -105,22 +105,22 @@ impl Weight {
/// Checked addition.
///
/// Computes `self + rhs` returning `None` if an overflow occurred.
/// Computes `self + rhs` returning [`None`] if an overflow occurred.
pub fn checked_add(self, rhs: Self) -> Option<Self> { self.0.checked_add(rhs.0).map(Self) }
/// Checked subtraction.
///
/// Computes `self - rhs` returning `None` if an overflow occurred.
/// Computes `self - rhs` returning [`None`] if an overflow occurred.
pub fn checked_sub(self, rhs: Self) -> Option<Self> { self.0.checked_sub(rhs.0).map(Self) }
/// Checked multiplication.
///
/// Computes `self * rhs` returning `None` if an overflow occurred.
/// Computes `self * rhs` returning [`None`] if an overflow occurred.
pub fn checked_mul(self, rhs: u64) -> Option<Self> { self.0.checked_mul(rhs).map(Self) }
/// Checked division.
///
/// Computes `self / rhs` returning `None` if `rhs == 0`.
/// Computes `self / rhs` returning [`None`] if `rhs == 0`.
pub fn checked_div(self, rhs: u64) -> Option<Self> { self.0.checked_div(rhs).map(Self) }
}