units: Add #[inline] attributes to simple functions
What changed, and why it matters
This commit only adds #[inline] hints to small, simple functions in the rust-bitcoin units crate. It is a performance-oriented code-quality change with no functional or security impact.
No security action required. Treat as a normal performance/refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch adds #[inline] attributes to trivial/delegating functions across 20 files in units/src. Examples include to_sat/from_sat constructors, Display::fmt, error::source, serde helpers, checked arithmetic wrappers, and From/TryFrom conversions. No logic was changed, no bounds checks were removed, and no unsafe code was introduced. The change is purely an optimization hint to the Rust compiler.
Changed components
units/src/amount/*units/src/block.rsunits/src/fee_rate/*units/src/internal_macros.rsunits/src/locktime/*units/src/parse_int.rsunits/src/pow.rsunits/src/result.rsunits/src/sequence.rsunits/src/time.rsunits/src/weight.rsInspect captured patch +306 / −0
diff --git a/units/src/amount/error.rs b/units/src/amount/error.rs
index 61fef986..fab2338c 100644
--- a/units/src/amount/error.rs
+++ b/units/src/amount/error.rs
@@ -109,6 +109,7 @@ impl fmt::Display for ParseAmountError {
#[cfg(feature = "std")]
impl std::error::Error for ParseAmountError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use ParseAmountErrorInner as E;
@@ -136,6 +137,7 @@ impl OutOfRangeError {
/// Returns the minimum and maximum allowed values for the type that was parsed.
///
/// This can be used to give a hint to the user which values are allowed.
+ #[inline]
pub fn valid_range(self) -> (i64, u64) {
match self.is_signed {
true => (i64::MIN, i64::MAX as u64),
@@ -144,15 +146,19 @@ impl OutOfRangeError {
}
/// Returns true if the input value was larger than the maximum allowed value.
+ #[inline]
pub fn is_above_max(self) -> bool { self.is_greater_than_max }
/// Returns true if the input value was smaller than the minimum allowed value.
+ #[inline]
pub fn is_below_min(self) -> bool { !self.is_greater_than_max }
#[cfg(test)]
+ #[inline]
pub(crate) fn too_big(is_signed: bool) -> Self { Self { is_signed, is_greater_than_max: true } }
#[cfg(test)]
+ #[inline]
pub(crate) fn too_small() -> Self {
Self {
// implied - negative() is used for the other
@@ -161,6 +167,7 @@ impl OutOfRangeError {
}
}
+ #[inline]
pub(crate) fn negative() -> Self {
Self {
// implied - too_small() is used for the other
@@ -186,6 +193,7 @@ impl fmt::Display for OutOfRangeError {
#[cfg(feature = "std")]
impl std::error::Error for OutOfRangeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -214,6 +222,7 @@ impl fmt::Display for TooPreciseError {
#[cfg(feature = "std")]
impl std::error::Error for TooPreciseError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -246,6 +255,7 @@ impl fmt::Display for InputTooLargeError {
#[cfg(feature = "std")]
impl std::error::Error for InputTooLargeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -262,6 +272,7 @@ impl From<Infallible> for MissingDigitsError {
}
impl fmt::Display for MissingDigitsError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.kind {
MissingDigitsKind::Empty => f.write_str("the input is empty"),
@@ -273,6 +284,7 @@ impl fmt::Display for MissingDigitsError {
#[cfg(feature = "std")]
impl std::error::Error for MissingDigitsError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -309,6 +321,7 @@ impl fmt::Display for InvalidCharacterError {
#[cfg(feature = "std")]
impl std::error::Error for InvalidCharacterError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -341,6 +354,7 @@ impl fmt::Display for BadPositionError {
#[cfg(feature = "std")]
impl std::error::Error for BadPositionError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -369,6 +383,7 @@ impl fmt::Display for ParseDenominationError {
#[cfg(feature = "std")]
impl std::error::Error for ParseDenominationError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Unknown(ref e) => Some(e),
@@ -394,6 +409,7 @@ impl fmt::Display for MissingDenominationError {
#[cfg(feature = "std")]
impl std::error::Error for MissingDenominationError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -407,6 +423,7 @@ impl From<Infallible> for UnknownDenominationError {
}
impl fmt::Display for UnknownDenominationError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.unknown_variant("bitcoin denomination", f)
}
@@ -414,6 +431,7 @@ impl fmt::Display for UnknownDenominationError {
#[cfg(feature = "std")]
impl std::error::Error for UnknownDenominationError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -434,6 +452,7 @@ impl fmt::Display for PossiblyConfusingDenominationError {
#[cfg(feature = "std")]
impl std::error::Error for PossiblyConfusingDenominationError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -445,11 +464,13 @@ pub struct AmountDecoderError(pub(super) AmountDecoderErrorInner);
#[cfg(feature = "encoding")]
impl AmountDecoderError {
/// Constructs an EOF error.
+ #[inline]
pub(super) fn eof(e: encoding::UnexpectedEofError) -> Self {
Self(AmountDecoderErrorInner::UnexpectedEof(e))
}
/// Constructs an out of range (`Amount::from_sat`) error.
+ #[inline]
pub(super) fn out_of_range(e: OutOfRangeError) -> Self {
Self(AmountDecoderErrorInner::OutOfRange(e))
}
@@ -484,6 +505,7 @@ impl fmt::Display for AmountDecoderError {
#[cfg(feature = "encoding")]
#[cfg(feature = "std")]
impl std::error::Error for AmountDecoderError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use AmountDecoderErrorInner as E;
diff --git a/units/src/amount/mod.rs b/units/src/amount/mod.rs
index 71b3fa51..fe2064e8 100644
--- a/units/src/amount/mod.rs
+++ b/units/src/amount/mod.rs
@@ -112,6 +112,7 @@ impl Denomination {
pub const SAT: Self = Self::Satoshi;
/// The number of decimal places more than a satoshi.
+ #[inline]
fn precision(self) -> i8 {
match self {
Self::Bitcoin => -8,
@@ -125,6 +126,7 @@ impl Denomination {
}
/// Returns a string representation of this denomination.
+ #[inline]
fn as_str(self) -> &'static str {
match self {
Self::Bitcoin => "BTC",
@@ -138,6 +140,7 @@ impl Denomination {
}
/// The different `str` forms of denominations that are recognized.
+ #[inline]
fn forms(s: &str) -> Option<Self> {
match s {
"BTC" | "btc" => Some(Self::Bitcoin),
@@ -157,6 +160,7 @@ impl Denomination {
const CONFUSING_FORMS: [&str; 6] = ["CBTC", "Cbtc", "MBTC", "Mbtc", "UBTC", "Ubtc"];
impl fmt::Display for Denomination {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(self.as_str()) }
}
@@ -353,6 +357,7 @@ impl From<Infallible> for InnerParseError {
}
impl InnerParseError {
+ #[inline]
fn convert(self, is_signed: bool) -> ParseAmountError {
match self {
Self::Overflow { is_negative } =>
@@ -395,6 +400,7 @@ struct FormatOptions {
}
impl FormatOptions {
+ #[inline]
fn from_formatter(f: &fmt::Formatter) -> Self {
Self {
fill: f.fill(),
@@ -408,6 +414,7 @@ impl FormatOptions {
}
impl Default for FormatOptions {
+ #[inline]
fn default() -> Self {
Self {
fill: ' ',
@@ -592,6 +599,7 @@ pub struct Display {
impl Display {
/// Makes subsequent calls to `Display::fmt` display denomination.
+ #[inline]
#[must_use]
pub fn show_denomination(mut self) -> Self {
match &mut self.style {
@@ -604,6 +612,7 @@ impl Display {
}
impl fmt::Display for Display {
+ #[inline]
#[rustfmt::skip]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let format_options = FormatOptions::from_formatter(f);
diff --git a/units/src/amount/result.rs b/units/src/amount/result.rs
index 723fbae1..c70ded04 100644
--- a/units/src/amount/result.rs
+++ b/units/src/amount/result.rs
@@ -14,16 +14,20 @@ use crate::internal_macros::{
use crate::result::{MathOp, NumOpError, NumOpResult, OptionExt};
impl From<Amount> for NumOpResult<Amount> {
+ #[inline]
fn from(a: Amount) -> Self { Self::Valid(a) }
}
impl From<&Amount> for NumOpResult<Amount> {
+ #[inline]
fn from(a: &Amount) -> Self { Self::Valid(*a) }
}
impl From<SignedAmount> for NumOpResult<SignedAmount> {
+ #[inline]
fn from(a: SignedAmount) -> Self { Self::Valid(a) }
}
impl From<&SignedAmount> for NumOpResult<SignedAmount> {
+ #[inline]
fn from(a: &SignedAmount) -> Self { Self::Valid(*a) }
}
@@ -204,6 +208,7 @@ impl_sub_assign_for_results!(SignedAmount);
impl ops::Neg for SignedAmount {
type Output = Self;
+ #[inline]
fn neg(self) -> Self::Output {
Self::from_sat(self.to_sat().neg()).expect("all +ve and -ve values are valid")
}
diff --git a/units/src/amount/serde.rs b/units/src/amount/serde.rs
index 4e7ea1fb..0cdf371b 100644
--- a/units/src/amount/serde.rs
+++ b/units/src/amount/serde.rs
@@ -64,6 +64,7 @@ pub mod as_sat {
use crate::SignedAmount;
+ #[inline]
pub fn serialize<A, S: Serializer>(a: &A, s: S) -> Result<S::Ok, S::Error>
where
A: Into<SignedAmount> + Copy,
@@ -72,6 +73,7 @@ pub mod as_sat {
i64::serialize(&amount.to_sat(), s)
}
+ #[inline]
pub fn deserialize<'d, A, D: Deserializer<'d>>(d: D) -> Result<A, D::Error>
where
A: TryFrom<SignedAmount>,
@@ -96,6 +98,7 @@ pub mod as_sat {
use crate::SignedAmount;
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<A, S: Serializer>(a: &Option<A>, s: S) -> Result<S::Ok, S::Error>
where
@@ -128,6 +131,7 @@ pub mod as_sat {
write!(formatter, "an Option<i64>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -135,6 +139,7 @@ pub mod as_sat {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
@@ -228,6 +233,7 @@ pub mod as_btc {
use super::DisplayFullError;
use crate::amount::{Denomination, SignedAmount};
+ #[inline]
pub fn serialize<A, S: Serializer>(a: &A, s: S) -> Result<S::Ok, S::Error>
where
A: Into<SignedAmount> + Copy,
@@ -236,6 +242,7 @@ pub mod as_btc {
f64::serialize(&amount.to_float_in(Denomination::Bitcoin), s)
}
+ #[inline]
pub fn deserialize<'d, A, D: Deserializer<'d>>(d: D) -> Result<A, D::Error>
where
A: TryFrom<SignedAmount>,
@@ -262,6 +269,7 @@ pub mod as_btc {
use crate::amount::{Denomination, SignedAmount};
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<A, S: Serializer>(a: &Option<A>, s: S) -> Result<S::Ok, S::Error>
where
@@ -294,6 +302,7 @@ pub mod as_btc {
write!(formatter, "an Option<f64>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -301,6 +310,7 @@ pub mod as_btc {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
@@ -395,6 +405,7 @@ pub mod as_str {
use super::DisplayFullError;
use crate::amount::{Denomination, SignedAmount};
+ #[inline]
pub fn serialize<A, S: Serializer>(a: &A, s: S) -> Result<S::Ok, S::Error>
where
A: Into<SignedAmount> + Copy,
@@ -403,6 +414,7 @@ pub mod as_str {
str::serialize(&amount.to_string_in(Denomination::Bitcoin), s)
}
+ #[inline]
pub fn deserialize<'d, A, D: Deserializer<'d>>(d: D) -> Result<A, D::Error>
where
A: TryFrom<SignedAmount>,
@@ -429,6 +441,7 @@ pub mod as_str {
use crate::amount::{Denomination, SignedAmount};
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<A, S: Serializer>(a: &Option<A>, s: S) -> Result<S::Ok, S::Error>
where
@@ -461,6 +474,7 @@ pub mod as_str {
write!(formatter, "an Option<String>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -468,6 +482,7 @@ pub mod as_str {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs
index 59c62945..0fb4649e 100644
--- a/units/src/amount/signed.rs
+++ b/units/src/amount/signed.rs
@@ -66,6 +66,7 @@ mod encapsulate {
/// # use bitcoin_units::SignedAmount;
/// assert_eq!(SignedAmount::ONE_BTC.to_sat(), 100_000_000);
/// ```
+ #[inline]
pub const fn to_sat(self) -> i64 { self.0 }
/// Constructs a new [`SignedAmount`] from the given number of satoshis.
@@ -83,6 +84,7 @@ mod encapsulate {
/// assert_eq!(amount.to_sat(), sat);
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
pub const fn from_sat(satoshi: i64) -> Result<Self, OutOfRangeError> {
if satoshi < Self::MIN.to_sat() {
Err(OutOfRangeError { is_signed: true, is_greater_than_max: false })
@@ -114,6 +116,7 @@ impl SignedAmount {
///
/// Accepts an `i32` which is guaranteed to be in range for the type, but which can only
/// represent roughly -21.47 to 21.47 BTC.
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub const fn from_sat_i32(satoshi: i32) -> Self {
let sats = satoshi as i64; // cannot use i64::from in a constfn
@@ -128,6 +131,7 @@ impl SignedAmount {
/// # Errors:
///
/// Returns an [`OutOfRangeError`] if the satoshi value > [`Self::MAX_MONEY`].
+ #[inline]
#[allow(clippy::missing_panics_doc)]
fn from_sat_u64(satoshi: u64) -> Result<Self, ParseAmountError> {
// u64 -> i64 only fails if value is greater than i64::MAX, which is also > Self::MAX_MONEY.
@@ -157,12 +161,14 @@ impl SignedAmount {
/// assert_eq!(amount.to_sat(), -1_000_000);
/// # Ok::<_, amount::ParseAmountError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<Self, ParseAmountError> {
Self::from_float_in(btc, Denomination::Bitcoin)
}
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`].
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub fn from_int_btc<T: Into<i16>>(whole_bitcoin: T) -> Self {
Self::from_btc_i16(whole_bitcoin.into())
@@ -170,6 +176,7 @@ impl SignedAmount {
/// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`]
/// in const context.
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub const fn from_btc_i16(whole_bitcoin: i16) -> Self {
let btc = const_casts::i16_to_i64(whole_bitcoin);
@@ -189,6 +196,7 @@ impl SignedAmount {
/// # Errors
///
/// If the amount is too big (positive or negative) or too precise.
+ #[inline]
pub fn from_str_in(s: &str, denom: Denomination) -> Result<Self, ParseAmountError> {
parse_signed_to_satoshi(s, denom)
.map(|(_, amount)| amount)
@@ -212,6 +220,7 @@ impl SignedAmount {
/// assert_eq!(amount, SignedAmount::from_sat_i32(10_000_000));
/// # Ok::<_, amount::ParseError>(())
/// ```
+ #[inline]
pub fn from_str_with_denomination(s: &str) -> Result<Self, ParseError> {
let (amt, denom) = split_amount_and_denomination(s)?;
Self::from_str_in(amt, denom).map_err(|e| ParseError(ParseErrorInner::Amount(e)))
@@ -229,6 +238,7 @@ impl SignedAmount {
/// assert_eq!(amount.to_float_in(Denomination::Bitcoin), 0.001);
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
#[allow(clippy::missing_panics_doc)]
pub fn to_float_in(self, denom: Denomination) -> f64 {
@@ -277,6 +287,7 @@ impl SignedAmount {
/// assert_eq!(amount.to_btc(), amount.to_float_in(Denomination::Bitcoin));
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) }
@@ -287,6 +298,7 @@ impl SignedAmount {
/// If the amount is too big (positive or negative) or too precise.
///
/// Please be aware of the risk of using floating-point numbers.
+ #[inline]
#[cfg(feature = "alloc")]
pub fn from_float_in(value: f64, denom: Denomination) -> Result<Self, ParseAmountError> {
// This is inefficient, but the safest way to deal with this. The parsing logic is safe.
@@ -309,6 +321,7 @@ impl SignedAmount {
/// assert_eq!(output, "0.1");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[must_use]
pub fn display_in(self, denomination: Denomination) -> Display {
Display {
@@ -323,6 +336,7 @@ impl SignedAmount {
///
/// This will use BTC for values greater than or equal to 1 BTC and satoshis otherwise. To
/// avoid confusion the denomination is always shown.
+ #[inline]
#[must_use]
pub fn display_dynamic(self) -> Display {
Display {
@@ -344,6 +358,7 @@ impl SignedAmount {
/// assert_eq!(amount.to_string_in(Denomination::Bitcoin), "0.1");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_string_in(self, denom: Denomination) -> String { self.display_in(denom).to_string() }
@@ -358,6 +373,7 @@ impl SignedAmount {
/// assert_eq!(amount.to_string_with_denomination(Denomination::Bitcoin), "0.1 BTC");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_string_with_denomination(self, denom: Denomination) -> String {
self.display_in(denom).show_denomination().to_string()
@@ -366,6 +382,7 @@ impl SignedAmount {
/// Gets the absolute value of this [`SignedAmount`].
///
/// This function never overflows or panics, unlike `i64::abs()`.
+ #[inline]
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub const fn abs(self) -> Self {
@@ -377,6 +394,7 @@ impl SignedAmount {
}
/// Gets the absolute value of this [`SignedAmount`] returning [`Amount`].
+ #[inline]
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn unsigned_abs(self) -> Amount {
@@ -388,6 +406,7 @@ impl SignedAmount {
/// - `0` if the amount is zero
/// - `1` if the amount is positive
/// - `-1` if the amount is negative
+ #[inline]
#[must_use]
pub fn signum(self) -> i64 { self.to_sat().signum() }
@@ -395,12 +414,14 @@ impl SignedAmount {
///
/// Returns `true` if this [`SignedAmount`] is positive and `false` if
/// this [`SignedAmount`] is zero or negative.
+ #[inline]
pub fn is_positive(self) -> bool { self.to_sat().is_positive() }
/// Checks if this [`SignedAmount`] is negative.
///
/// Returns `true` if this [`SignedAmount`] is negative and `false` if
/// this [`SignedAmount`] is zero or positive.
+ #[inline]
pub fn is_negative(self) -> bool { self.to_sat().is_negative() }
/// Returns the absolute value of this [`SignedAmount`].
@@ -416,6 +437,7 @@ impl SignedAmount {
/// Checked addition.
///
/// Returns [`None`] if the sum is above [`SignedAmount::MAX`] or below [`SignedAmount::MIN`].
+ #[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -432,6 +454,7 @@ impl SignedAmount {
///
/// Returns [`None`] if the difference is above [`SignedAmount::MAX`] or below
/// [`SignedAmount::MIN`].
+ #[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -448,6 +471,7 @@ impl SignedAmount {
///
/// Returns [`None`] if the product is above [`SignedAmount::MAX`] or below
/// [`SignedAmount::MIN`].
+ #[inline]
#[must_use]
pub const fn checked_mul(self, rhs: i64) -> Option<Self> {
// No `map()` in const context.
@@ -465,6 +489,7 @@ impl SignedAmount {
/// Be aware that integer division loses the remainder if no exact division can be made.
///
/// Returns [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_div(self, rhs: i64) -> Option<Self> {
// No `map()` in const context.
@@ -480,6 +505,7 @@ impl SignedAmount {
/// Checked remainder.
///
/// Returns [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_rem(self, rhs: i64) -> Option<Self> {
// No `map()` in const context.
@@ -495,6 +521,7 @@ impl SignedAmount {
/// Subtraction that doesn't allow negative [`SignedAmount`]s.
///
/// Returns [`None`] if either `self`, `rhs` or the result is strictly negative.
+ #[inline]
#[must_use]
pub fn positive_sub(self, rhs: Self) -> Option<Self> {
if self.is_negative() || rhs.is_negative() || rhs > self {
@@ -509,6 +536,7 @@ impl SignedAmount {
/// # Errors
///
/// If the amount is negative.
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub fn to_unsigned(self) -> Result<Amount, OutOfRangeError> {
if self.is_negative() {
@@ -524,6 +552,7 @@ impl SignedAmount {
crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(SignedAmount, to_sat);
impl default::Default for SignedAmount {
+ #[inline]
fn default() -> Self { Self::ZERO }
}
@@ -536,6 +565,7 @@ impl fmt::Debug for SignedAmount {
// No one should depend on a binding contract for Display for this type.
// Just using Bitcoin denominated string.
impl fmt::Display for SignedAmount {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.display_in(Denomination::Bitcoin).show_denomination(), f)
}
@@ -566,6 +596,7 @@ impl FromStr for SignedAmount {
}
impl From<Amount> for SignedAmount {
+ #[inline]
fn from(value: Amount) -> Self {
let v = value.to_sat() as i64; // Cast ok, signed amount and amount share positive range.
Self::from_sat(v).expect("all amounts are valid signed amounts")
diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs
index cf207586..7b150fa3 100644
--- a/units/src/amount/unsigned.rs
+++ b/units/src/amount/unsigned.rs
@@ -71,6 +71,7 @@ mod encapsulate {
/// # use bitcoin_units::Amount;
/// assert_eq!(Amount::ONE_BTC.to_sat(), 100_000_000);
/// ```
+ #[inline]
pub const fn to_sat(self) -> u64 { self.0 }
/// Constructs a new [`Amount`] from the given number of satoshis.
@@ -88,6 +89,7 @@ mod encapsulate {
/// assert_eq!(amount.to_sat(), sat);
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
pub const fn from_sat(satoshi: u64) -> Result<Self, OutOfRangeError> {
if satoshi > Self::MAX_MONEY.to_sat() {
Err(OutOfRangeError { is_signed: false, is_greater_than_max: true })
@@ -118,6 +120,7 @@ impl Amount {
///
/// Accepts an `u32` which is guaranteed to be in range for the type, but which can only
/// represent roughly 0 to 42.95 BTC.
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub const fn from_sat_u32(satoshi: u32) -> Self {
let sats = const_casts::u32_to_u64(satoshi);
@@ -144,12 +147,14 @@ impl Amount {
/// assert_eq!(amount.to_sat(), 1_000_000);
/// # Ok::<_, amount::ParseAmountError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn from_btc(btc: f64) -> Result<Self, ParseAmountError> {
Self::from_float_in(btc, Denomination::Bitcoin)
}
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`].
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub fn from_int_btc<T: Into<u16>>(whole_bitcoin: T) -> Self {
Self::from_btc_u16(whole_bitcoin.into())
@@ -157,6 +162,7 @@ impl Amount {
/// Converts from a value expressing a whole number of bitcoin to an [`Amount`]
/// in const context.
+ #[inline]
#[allow(clippy::missing_panics_doc)]
pub const fn from_btc_u16(whole_bitcoin: u16) -> Self {
let btc = const_casts::u16_to_u64(whole_bitcoin);
@@ -176,6 +182,7 @@ impl Amount {
/// # Errors
///
/// If the amount is too precise, negative, or greater than 21,000,000.
+ #[inline]
pub fn from_str_in(s: &str, denom: Denomination) -> Result<Self, ParseAmountError> {
let (is_neg, amount) =
parse_signed_to_satoshi(s, denom).map_err(|error| error.convert(false))?;
@@ -204,6 +211,7 @@ impl Amount {
/// assert_eq!(amount, Amount::from_sat_u32(10_000_000));
/// # Ok::<_, amount::ParseError>(())
/// ```
+ #[inline]
pub fn from_str_with_denomination(s: &str) -> Result<Self, ParseError> {
let (amt, denom) = split_amount_and_denomination(s)?;
Self::from_str_in(amt, denom).map_err(|e| ParseError(ParseErrorInner::Amount(e)))
@@ -221,6 +229,7 @@ impl Amount {
/// assert_eq!(amount.to_float_in(Denomination::Bitcoin), 0.001);
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
#[allow(clippy::missing_panics_doc)]
pub fn to_float_in(self, denom: Denomination) -> f64 {
@@ -239,6 +248,7 @@ impl Amount {
/// assert_eq!(amount.to_btc(), amount.to_float_in(Denomination::Bitcoin));
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) }
@@ -249,6 +259,7 @@ impl Amount {
/// If the amount is too big, too precise or negative.
///
/// Please be aware of the risk of using floating-point numbers.
+ #[inline]
#[cfg(feature = "alloc")]
pub fn from_float_in(value: f64, denom: Denomination) -> Result<Self, ParseAmountError> {
if value < 0.0 {
@@ -304,6 +315,7 @@ impl Amount {
/// assert_eq!(output, "0.1");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[must_use]
pub fn display_in(self, denomination: Denomination) -> Display {
Display {
@@ -318,6 +330,7 @@ impl Amount {
///
/// This will use BTC for values greater than or equal to 1 BTC and satoshis otherwise. To
/// avoid confusion the denomination is always shown.
+ #[inline]
#[must_use]
pub fn display_dynamic(self) -> Display {
Display {
@@ -339,6 +352,7 @@ impl Amount {
/// assert_eq!(amount.to_string_in(Denomination::Bitcoin), "0.1");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_string_in(self, denom: Denomination) -> String { self.display_in(denom).to_string() }
@@ -353,6 +367,7 @@ impl Amount {
/// assert_eq!(amount.to_string_with_denomination(Denomination::Bitcoin), "0.1 BTC");
/// # Ok::<_, amount::OutOfRangeError>(())
/// ```
+ #[inline]
#[cfg(feature = "alloc")]
pub fn to_string_with_denomination(self, denom: Denomination) -> String {
self.display_in(denom).show_denomination().to_string()
@@ -361,6 +376,7 @@ impl Amount {
/// Checked addition.
///
/// Returns [`None`] if the sum is larger than [`Amount::MAX`].
+ #[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -374,6 +390,7 @@ impl Amount {
/// Checked subtraction.
///
/// Returns [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -389,6 +406,7 @@ impl Amount {
/// Checked multiplication.
///
/// Returns [`None`] if the product is larger than [`Amount::MAX`].
+ #[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -406,6 +424,7 @@ impl Amount {
/// Be aware that integer division loses the remainder if no exact division can be made.
///
/// Returns [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -421,6 +440,7 @@ impl Amount {
/// Checked remainder.
///
/// Returns [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_rem(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -434,6 +454,7 @@ impl Amount {
}
/// Converts to a signed amount.
+ #[inline]
#[rustfmt::skip] // Moves code comments to the wrong line.
#[allow(clippy::missing_panics_doc)]
pub fn to_signed(self) -> SignedAmount {
@@ -445,6 +466,7 @@ impl Amount {
///
/// Since `SignedAmount::MIN` is equivalent to `-Amount::MAX` subtraction of two signed amounts
/// can never overflow a `SignedAmount`.
+ #[inline]
#[must_use]
pub fn signed_sub(self, rhs: Self) -> SignedAmount {
(self.to_signed() - rhs.to_signed())
@@ -541,6 +563,7 @@ impl Amount {
crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(Amount, to_sat);
impl default::Default for Amount {
+ #[inline]
fn default() -> Self { Self::ZERO }
}
@@ -553,6 +576,7 @@ impl fmt::Debug for Amount {
// No one should depend on a binding contract for Display for this type.
// Just using Bitcoin denominated string.
impl fmt::Display for Amount {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.display_in(Denomination::Bitcoin).show_denomination(), f)
}
@@ -585,6 +609,7 @@ impl FromStr for Amount {
impl TryFrom<SignedAmount> for Amount {
type Error = OutOfRangeError;
+ #[inline]
fn try_from(value: SignedAmount) -> Result<Self, Self::Error> { value.to_unsigned() }
}
@@ -598,6 +623,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for Amount {
type Encoder<'e> = AmountEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
AmountEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_sat().to_le_bytes(),
@@ -628,6 +654,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for Amount {
type Decoder = AmountDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { AmountDecoder(encoding::ArrayDecoder::<8>::new()) }
}
diff --git a/units/src/block.rs b/units/src/block.rs
index 5eeaaa48..8978df6a 100644
--- a/units/src/block.rs
+++ b/units/src/block.rs
@@ -67,16 +67,19 @@ macro_rules! impl_u32_wrapper {
}
impl fmt::Display for $newtype {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
}
crate::parse_int::impl_parse_str_from_int_infallible!($newtype, u32, from);
impl From<u32> for $newtype {
+ #[inline]
fn from(inner: u32) -> Self { Self::from_u32(inner) }
}
impl From<$newtype> for u32 {
+ #[inline]
fn from(height: $newtype) -> Self { height.to_u32() }
}
@@ -139,18 +142,22 @@ impl BlockHeight {
pub const MAX: Self = Self(u32::MAX);
/// Constructs a new block height from a `u32`.
+ #[inline]
pub const fn from_u32(inner: u32) -> Self { Self(inner) }
/// Returns block height as a `u32`.
+ #[inline]
pub const fn to_u32(self) -> u32 { self.0 }
/// Attempt to subtract two [`BlockHeight`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_sub(self, other: Self) -> Option<BlockHeightInterval> {
self.to_u32().checked_sub(other.to_u32()).map(BlockHeightInterval)
}
/// Attempt to add an interval to this [`BlockHeight`], returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_add(self, other: BlockHeightInterval) -> Option<Self> {
self.to_u32().checked_add(other.to_u32()).map(Self)
@@ -182,6 +189,7 @@ impl From<absolute::Height> for BlockHeight {
///
/// An absolute locktime block height has a maximum value of [`absolute::LOCK_TIME_THRESHOLD`]
/// minus one, while [`BlockHeight`] may take the full range of `u32`.
+ #[inline]
fn from(h: absolute::Height) -> Self { Self::from_u32(h.to_u32()) }
}
@@ -192,6 +200,7 @@ impl TryFrom<BlockHeight> for absolute::Height {
///
/// An absolute locktime block height has a maximum value of [`absolute::LOCK_TIME_THRESHOLD`]
/// minus one, while [`BlockHeight`] may take the full range of `u32`.
+ #[inline]
fn try_from(h: BlockHeight) -> Result<Self, Self::Error> { Self::from_u32(h.to_u32()) }
}
@@ -205,6 +214,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for BlockHeight {
type Encoder<'e> = BlockHeightEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
BlockHeightEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_u32().to_le_bytes(),
@@ -231,6 +241,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for BlockHeight {
type Decoder = BlockHeightDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { BlockHeightDecoder(encoding::ArrayDecoder::<4>::new()) }
}
@@ -256,18 +267,22 @@ impl BlockHeightInterval {
pub const MAX: Self = Self(u32::MAX);
/// Constructs a new block interval from a `u32`.
+ #[inline]
pub const fn from_u32(inner: u32) -> Self { Self(inner) }
/// Returns block interval as a `u32`.
+ #[inline]
pub const fn to_u32(self) -> u32 { self.0 }
/// Attempt to subtract two [`BlockHeightInterval`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_sub(self, other: Self) -> Option<Self> {
self.to_u32().checked_sub(other.to_u32()).map(Self)
}
/// Attempt to add two [`BlockHeightInterval`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_add(self, other: Self) -> Option<Self> {
self.to_u32().checked_add(other.to_u32()).map(Self)
@@ -281,6 +296,7 @@ impl From<relative::NumberOfBlocks> for BlockHeightInterval {
///
/// A relative locktime block height has a maximum value of `u16::MAX` where as a
/// [`BlockHeightInterval`] is a thin wrapper around a `u32`, the two types are not interchangeable.
+ #[inline]
fn from(h: relative::NumberOfBlocks) -> Self { Self::from_u32(h.to_height().into()) }
}
@@ -291,6 +307,7 @@ impl TryFrom<BlockHeightInterval> for relative::NumberOfBlocks {
///
/// A relative locktime block height has a maximum value of `u16::MAX` where as a
/// [`BlockHeightInterval`] is a thin wrapper around a `u32`, the two types are not interchangeable.
+ #[inline]
fn try_from(h: BlockHeightInterval) -> Result<Self, Self::Error> {
u16::try_from(h.to_u32())
.map(Self::from)
@@ -323,9 +340,11 @@ impl BlockMtp {
pub const MAX: Self = Self(u32::MAX);
/// Constructs a new block MTP from a `u32`.
+ #[inline]
pub const fn from_u32(inner: u32) -> Self { Self(inner) }
/// Returns block MTP as a `u32`.
+ #[inline]
pub const fn to_u32(self) -> u32 { self.0 }
/// Constructs a [`BlockMtp`] by computing the median‐time‐past from the last 11 block timestamps
@@ -333,18 +352,21 @@ impl BlockMtp {
/// Because block timestamps are not monotonic, this function internally sorts them;
/// it is therefore not important what order they appear in the array; use whatever
/// is most convenient.
+ #[inline]
pub fn new(mut timestamps: [crate::BlockTime; 11]) -> Self {
timestamps.sort_unstable();
Self::from_u32(u32::from(timestamps[5]))
}
/// Attempt to subtract two [`BlockMtp`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_sub(self, other: Self) -> Option<BlockMtpInterval> {
self.to_u32().checked_sub(other.to_u32()).map(BlockMtpInterval)
}
/// Attempt to add an interval to this [`BlockMtp`], returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_add(self, other: BlockMtpInterval) -> Option<Self> {
self.to_u32().checked_add(other.to_u32()).map(Self)
@@ -358,6 +380,7 @@ impl From<absolute::MedianTimePast> for BlockMtp {
///
/// An absolute locktime MTP has a minimum value of [`absolute::LOCK_TIME_THRESHOLD`],
/// while [`BlockMtp`] may take the full range of `u32`.
+ #[inline]
fn from(h: absolute::MedianTimePast) -> Self { Self::from_u32(h.to_u32()) }
}
@@ -368,6 +391,7 @@ impl TryFrom<BlockMtp> for absolute::MedianTimePast {
///
/// An absolute locktime MTP has a minimum value of [`absolute::LOCK_TIME_THRESHOLD`],
/// while [`BlockMtp`] may take the full range of `u32`.
+ #[inline]
fn try_from(h: BlockMtp) -> Result<Self, Self::Error> { Self::from_u32(h.to_u32()) }
}
@@ -393,9 +417,11 @@ impl BlockMtpInterval {
pub const MAX: Self = Self(u32::MAX);
/// Constructs a new block MTP interval from a `u32`.
+ #[inline]
pub const fn from_u32(inner: u32) -> Self { Self(inner) }
/// Returns block MTP interval as a `u32`.
+ #[inline]
pub const fn to_u32(self) -> u32 { self.0 }
/// Converts a [`BlockMtpInterval`] to a [`locktime::relative::NumberOf512Seconds`], rounding down.
@@ -431,12 +457,14 @@ impl BlockMtpInterval {
}
/// Attempt to subtract two [`BlockMtpInterval`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_sub(self, other: Self) -> Option<Self> {
self.to_u32().checked_sub(other.to_u32()).map(Self)
}
/// Attempt to add two [`BlockMtpInterval`]s, returning `None` if overflow occurred.
+ #[inline]
#[must_use]
pub fn checked_add(self, other: Self) -> Option<Self> {
self.to_u32().checked_add(other.to_u32()).map(Self)
@@ -451,6 +479,7 @@ impl From<relative::NumberOf512Seconds> for BlockMtpInterval {
/// A relative locktime MTP interval has a resolution of 512 seconds, and a maximum value
/// of `u16::MAX` 512-second intervals. [`BlockMtpInterval`] may take the full range of
/// `u32`.
+ #[inline]
fn from(h: relative::NumberOf512Seconds) -> Self { Self::from_u32(h.to_seconds()) }
}
@@ -562,6 +591,7 @@ crate::internal_macros::impl_add_assign!(BlockMtpInterval);
crate::internal_macros::impl_sub_assign!(BlockMtpInterval);
impl core::iter::Sum for BlockHeightInterval {
+ #[inline]
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sum = iter.map(Self::to_u32).sum();
Self::from_u32(sum)
@@ -569,6 +599,7 @@ impl core::iter::Sum for BlockHeightInterval {
}
impl<'a> core::iter::Sum<&'a Self> for BlockHeightInterval {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
@@ -579,6 +610,7 @@ impl<'a> core::iter::Sum<&'a Self> for BlockHeightInterval {
}
impl core::iter::Sum for BlockMtpInterval {
+ #[inline]
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sum = iter.map(Self::to_u32).sum();
Self::from_u32(sum)
@@ -586,6 +618,7 @@ impl core::iter::Sum for BlockMtpInterval {
}
impl<'a> core::iter::Sum<&'a Self> for BlockMtpInterval {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
diff --git a/units/src/fee_rate/mod.rs b/units/src/fee_rate/mod.rs
index 5b1efd5f..942bf7a9 100644
--- a/units/src/fee_rate/mod.rs
+++ b/units/src/fee_rate/mod.rs
@@ -29,9 +29,11 @@ mod encapsulate {
impl FeeRate {
/// Constructs a new [`FeeRate`] from satoshis per 1,000,000 virtual bytes.
+ #[inline]
pub(crate) const fn from_sat_per_mvb(sat_mvb: u64) -> Self { Self(sat_mvb) }
/// Converts to sat/MvB.
+ #[inline]
pub(crate) const fn to_sat_per_mvb(self) -> u64 { self.0 }
}
}
@@ -62,12 +64,14 @@ impl FeeRate {
pub const DUST: Self = Self::from_sat_per_vb(3);
/// Constructs a new [`FeeRate`] from satoshis per 1000 weight units.
+ #[inline]
pub const fn from_sat_per_kwu(sat_kwu: u32) -> Self {
let fee_rate = (const_casts::u32_to_u64(sat_kwu)) * 4_000;
Self::from_sat_per_mvb(fee_rate)
}
/// Constructs a new [`FeeRate`] from amount per 1000 weight units.
+ #[inline]
pub const fn from_per_kwu(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(4_000) {
@@ -77,12 +81,14 @@ impl FeeRate {
}
/// Constructs a new [`FeeRate`] from satoshis per virtual byte.
+ #[inline]
pub const fn from_sat_per_vb(sat_vb: u32) -> Self {
let fee_rate = (const_casts::u32_to_u64(sat_vb)) * 1_000_000;
Self::from_sat_per_mvb(fee_rate)
}
/// Constructs a new [`FeeRate`] from amount per virtual byte.
+ #[inline]
pub const fn from_per_vb(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(1_000_000) {
@@ -92,12 +98,14 @@ impl FeeRate {
}
/// Constructs a new [`FeeRate`] from satoshis per kilo virtual bytes (1,000 vbytes).
+ #[inline]
pub const fn from_sat_per_kvb(sat_kvb: u32) -> Self {
let fee_rate = (const_casts::u32_to_u64(sat_kvb)) * 1_000;
Self::from_sat_per_mvb(fee_rate)
}
/// Constructs a new [`FeeRate`] from satoshis per kilo virtual bytes (1,000 vbytes).
+ #[inline]
pub const fn from_per_kvb(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(1_000) {
@@ -107,26 +115,33 @@ impl FeeRate {
}
/// Converts to sat/kwu rounding down.
+ #[inline]
pub const fn to_sat_per_kwu_floor(self) -> u64 { self.to_sat_per_mvb() / 4_000 }
/// Converts to sat/kwu rounding up.
+ #[inline]
pub const fn to_sat_per_kwu_ceil(self) -> u64 { self.to_sat_per_mvb().div_ceil(4_000) }
/// Converts to sat/vB rounding down.
+ #[inline]
pub const fn to_sat_per_vb_floor(self) -> u64 { self.to_sat_per_mvb() / 1_000_000 }
/// Converts to sat/vB rounding up.
+ #[inline]
pub const fn to_sat_per_vb_ceil(self) -> u64 { self.to_sat_per_mvb().div_ceil(1_000_000) }
/// Converts to sat/kvb rounding down.
+ #[inline]
pub const fn to_sat_per_kvb_floor(self) -> u64 { self.to_sat_per_mvb() / 1_000 }
/// Converts to sat/kvb rounding up.
+ #[inline]
pub const fn to_sat_per_kvb_ceil(self) -> u64 { self.to_sat_per_mvb().div_ceil(1_000) }
/// Checked multiplication.
///
/// Computes `self * rhs`, returning [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -139,6 +154,7 @@ impl FeeRate {
/// Checked division.
///
/// Computes `self / rhs` returning [`None`] if `rhs == 0`.
+ #[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -151,6 +167,7 @@ impl FeeRate {
/// Checked addition.
///
/// Computes `self + rhs` returning [`None`] in case of overflow.
+ #[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -163,6 +180,7 @@ impl FeeRate {
/// Checked subtraction.
///
/// Computes `self - rhs`, returning [`None`] if overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -181,6 +199,7 @@ impl FeeRate {
/// If the calculation would overflow we saturate to [`Amount::MAX`]. Since such a fee can never
/// be paid this is meaningful as an error case while still removing the possibility of silently
/// wrapping.
+ #[inline]
pub const fn to_fee(self, weight: Weight) -> Amount {
// No `unwrap_or()` in const context.
match self.mul_by_weight(weight) {
@@ -246,6 +265,7 @@ crate::internal_macros::impl_add_assign!(FeeRate);
crate::internal_macros::impl_sub_assign!(FeeRate);
impl core::iter::Sum for FeeRate {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
@@ -255,6 +275,7 @@ impl core::iter::Sum for FeeRate {
}
impl<'a> core::iter::Sum<&'a Self> for FeeRate {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
diff --git a/units/src/fee_rate/serde.rs b/units/src/fee_rate/serde.rs
index 53b11b09..0cdd3bc5 100644
--- a/units/src/fee_rate/serde.rs
+++ b/units/src/fee_rate/serde.rs
@@ -35,10 +35,12 @@ pub mod as_sat_per_kwu_floor {
use crate::{Amount, FeeRate};
+ #[inline]
pub fn serialize<S: Serializer>(f: &FeeRate, s: S) -> Result<S::Ok, S::Error> {
u64::serialize(&f.to_sat_per_kwu_floor(), s)
}
+ #[inline]
pub fn deserialize<'d, D: Deserializer<'d>>(d: D) -> Result<FeeRate, D::Error> {
let sat = u64::deserialize(d)?;
FeeRate::from_per_kwu(
@@ -59,6 +61,7 @@ pub mod as_sat_per_kwu_floor {
use crate::FeeRate;
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<S: Serializer>(f: &Option<FeeRate>, s: S) -> Result<S::Ok, S::Error> {
match *f {
@@ -77,6 +80,7 @@ pub mod as_sat_per_kwu_floor {
write!(f, "an Option<u64>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -84,6 +88,7 @@ pub mod as_sat_per_kwu_floor {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
@@ -160,11 +165,13 @@ pub mod as_sat_per_vb_floor {
use crate::{Amount, FeeRate};
+ #[inline]
pub fn serialize<S: Serializer>(f: &FeeRate, s: S) -> Result<S::Ok, S::Error> {
u64::serialize(&f.to_sat_per_vb_floor(), s)
}
// Errors on overflow.
+ #[inline]
pub fn deserialize<'d, D: Deserializer<'d>>(d: D) -> Result<FeeRate, D::Error> {
let sat = u64::deserialize(d)?;
FeeRate::from_per_vb(
@@ -186,6 +193,7 @@ pub mod as_sat_per_vb_floor {
use crate::fee_rate::FeeRate;
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<S: Serializer>(f: &Option<FeeRate>, s: S) -> Result<S::Ok, S::Error> {
match *f {
@@ -204,6 +212,7 @@ pub mod as_sat_per_vb_floor {
write!(f, "an Option<u64>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -211,6 +220,7 @@ pub mod as_sat_per_vb_floor {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
@@ -288,11 +298,13 @@ pub mod as_sat_per_vb_ceil {
use crate::{Amount, FeeRate};
+ #[inline]
pub fn serialize<S: Serializer>(f: &FeeRate, s: S) -> Result<S::Ok, S::Error> {
u64::serialize(&f.to_sat_per_vb_ceil(), s)
}
// Errors on overflow.
+ #[inline]
pub fn deserialize<'d, D: Deserializer<'d>>(d: D) -> Result<FeeRate, D::Error> {
let sat = u64::deserialize(d)?;
FeeRate::from_per_vb(
@@ -314,6 +326,7 @@ pub mod as_sat_per_vb_ceil {
use crate::fee_rate::FeeRate;
+ #[inline]
#[allow(clippy::ref_option)] // API forced by serde.
pub fn serialize<S: Serializer>(f: &Option<FeeRate>, s: S) -> Result<S::Ok, S::Error> {
match *f {
@@ -332,6 +345,7 @@ pub mod as_sat_per_vb_ceil {
write!(f, "an Option<u64>")
}
+ #[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
@@ -339,6 +353,7 @@ pub mod as_sat_per_vb_ceil {
Ok(None)
}
+ #[inline]
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
@@ -423,5 +438,6 @@ impl fmt::Display for OverflowError {
#[cfg(feature = "std")]
impl std::error::Error for OverflowError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
diff --git a/units/src/internal_macros.rs b/units/src/internal_macros.rs
index 06fa4bfe..531ffbdf 100644
--- a/units/src/internal_macros.rs
+++ b/units/src/internal_macros.rs
@@ -73,10 +73,12 @@ pub(crate) use impl_op_for_references;
macro_rules! impl_add_assign {
($ty:ident) => {
impl core::ops::AddAssign<$ty> for $ty {
+ #[inline]
fn add_assign(&mut self, rhs: $ty) { *self = *self + rhs }
}
impl core::ops::AddAssign<&$ty> for $ty {
+ #[inline]
fn add_assign(&mut self, rhs: &$ty) { *self = *self + *rhs }
}
};
@@ -90,6 +92,7 @@ pub(crate) use impl_add_assign;
macro_rules! impl_add_assign_for_results {
($ty:ident) => {
impl ops::AddAssign<$ty> for NumOpResult<$ty> {
+ #[inline]
fn add_assign(&mut self, rhs: $ty) {
match self {
Self::Error(_) => *self = Self::Error(NumOpError::while_doing(MathOp::Add)),
@@ -99,6 +102,7 @@ macro_rules! impl_add_assign_for_results {
}
impl ops::AddAssign<Self> for NumOpResult<$ty> {
+ #[inline]
fn add_assign(&mut self, rhs: Self) {
match (&self, rhs) {
(Self::Valid(_), Self::Valid(rhs)) => *self += rhs,
@@ -117,6 +121,7 @@ pub(crate) use impl_add_assign_for_results;
macro_rules! impl_sub_assign_for_results {
($ty:ident) => {
impl ops::SubAssign<$ty> for NumOpResult<$ty> {
+ #[inline]
fn sub_assign(&mut self, rhs: $ty) {
match self {
Self::Error(_) => *self = Self::Error(NumOpError::while_doing(MathOp::Sub)),
@@ -126,6 +131,7 @@ macro_rules! impl_sub_assign_for_results {
}
impl ops::SubAssign<Self> for NumOpResult<$ty> {
+ #[inline]
fn sub_assign(&mut self, rhs: Self) {
match (&self, rhs) {
(Self::Valid(_), Self::Valid(rhs)) => *self -= rhs,
@@ -141,10 +147,12 @@ pub(crate) use impl_sub_assign_for_results;
macro_rules! impl_sub_assign {
($ty:ident) => {
impl core::ops::SubAssign<$ty> for $ty {
+ #[inline]
fn sub_assign(&mut self, rhs: $ty) { *self = *self - rhs }
}
impl core::ops::SubAssign<&$ty> for $ty {
+ #[inline]
fn sub_assign(&mut self, rhs: &$ty) { *self = *self - *rhs }
}
};
@@ -155,10 +163,12 @@ pub(crate) use impl_sub_assign;
macro_rules! impl_mul_assign {
($ty:ty, $rhs:ident) => {
impl core::ops::MulAssign<$rhs> for $ty {
+ #[inline]
fn mul_assign(&mut self, rhs: $rhs) { *self = *self * rhs }
}
impl core::ops::MulAssign<&$rhs> for $ty {
+ #[inline]
fn mul_assign(&mut self, rhs: &$rhs) { *self = *self * *rhs }
}
};
@@ -169,10 +179,12 @@ pub(crate) use impl_mul_assign;
macro_rules! impl_div_assign {
($ty:ty, $rhs:ident) => {
impl core::ops::DivAssign<$rhs> for $ty {
+ #[inline]
fn div_assign(&mut self, rhs: $rhs) { *self = *self / rhs }
}
impl core::ops::DivAssign<&$rhs> for $ty {
+ #[inline]
fn div_assign(&mut self, rhs: &$rhs) { *self = *self / *rhs }
}
};
diff --git a/units/src/locktime/absolute/error.rs b/units/src/locktime/absolute/error.rs
index 1cc49c4a..d498b2bd 100644
--- a/units/src/locktime/absolute/error.rs
+++ b/units/src/locktime/absolute/error.rs
@@ -32,6 +32,7 @@ impl fmt::Display for LockTimeDecoderError {
#[cfg(feature = "encoding")]
#[cfg(feature = "std")]
impl std::error::Error for LockTimeDecoderError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
@@ -46,9 +47,11 @@ pub struct IncompatibleHeightError {
impl IncompatibleHeightError {
/// Returns the value of the lock-by-time lock.
+ #[inline]
pub fn lock(&self) -> MedianTimePast { self.lock }
/// Returns the height that was erroneously used to try and satisfy a lock-by-time lock.
+ #[inline]
pub fn incompatible(&self) -> Height { self.incompatible }
}
@@ -69,6 +72,7 @@ impl fmt::Display for IncompatibleHeightError {
#[cfg(feature = "std")]
impl std::error::Error for IncompatibleHeightError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -83,9 +87,11 @@ pub struct IncompatibleTimeError {
impl IncompatibleTimeError {
/// Returns the value of the lock-by-height lock.
+ #[inline]
pub fn lock(&self) -> Height { self.lock }
/// Returns the MTP that was erroneously used to try and satisfy a lock-by-height lock.
+ #[inline]
pub fn incompatible(&self) -> MedianTimePast { self.incompatible }
}
@@ -106,6 +112,7 @@ impl fmt::Display for IncompatibleTimeError {
#[cfg(feature = "std")]
impl std::error::Error for IncompatibleTimeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -118,6 +125,7 @@ impl From<Infallible> for ParseHeightError {
}
impl fmt::Display for ParseHeightError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.display(f, "block height", 0, LOCK_TIME_THRESHOLD - 1)
}
@@ -126,10 +134,12 @@ impl fmt::Display for ParseHeightError {
#[cfg(feature = "std")]
impl std::error::Error for ParseHeightError {
// To be consistent with `write_err` we need to **not** return source if overflow occurred
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.0.source() }
}
impl From<ParseError> for ParseHeightError {
+ #[inline]
fn from(value: ParseError) -> Self { Self(value) }
}
@@ -142,6 +152,7 @@ impl From<Infallible> for ParseTimeError {
}
impl fmt::Display for ParseTimeError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.display(f, "block time", LOCK_TIME_THRESHOLD, u32::MAX)
}
@@ -150,10 +161,12 @@ impl fmt::Display for ParseTimeError {
#[cfg(feature = "std")]
impl std::error::Error for ParseTimeError {
// To be consistent with `write_err` we need to **not** return source if overflow occurred
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.0.source() }
}
impl From<ParseError> for ParseTimeError {
+ #[inline]
fn from(value: ParseError) -> Self { Self(value) }
}
@@ -172,6 +185,7 @@ pub(super) enum ParseError {
}
impl ParseError {
+ #[inline]
pub(super) fn invalid_int<S: Into<InputString>>(
s: S,
) -> impl FnOnce(core::num::ParseIntError) -> Self {
@@ -234,6 +248,7 @@ impl ParseError {
}
// To be consistent with `write_err` we need to **not** return source if overflow occurred
+ #[inline]
#[cfg(feature = "std")]
pub(super) fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use core::num::IntErrorKind;
@@ -258,14 +273,17 @@ impl From<Infallible> for ParseError {
}
impl From<ConversionError> for ParseError {
+ #[inline]
fn from(value: ConversionError) -> Self { Self::Conversion(value.input.into()) }
}
impl From<PrefixedHexError> for ParseError {
+ #[inline]
fn from(value: PrefixedHexError) -> Self { Self::PrefixedHex(value) }
}
impl From<UnprefixedHexError> for ParseError {
+ #[inline]
fn from(value: UnprefixedHexError) -> Self { Self::UnprefixedHex(value) }
}
@@ -281,11 +299,13 @@ pub struct ConversionError {
impl ConversionError {
/// Constructs a new `ConversionError` from an invalid `n` when expecting a height value.
+ #[inline]
pub(super) const fn invalid_height(n: u32) -> Self {
Self { unit: LockTimeUnit::Blocks, input: n }
}
/// Constructs a new `ConversionError` from an invalid `n` when expecting a time value.
+ #[inline]
pub(super) const fn invalid_time(n: u32) -> Self {
Self { unit: LockTimeUnit::Seconds, input: n }
}
@@ -303,6 +323,7 @@ impl fmt::Display for ConversionError {
#[cfg(feature = "std")]
impl std::error::Error for ConversionError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
diff --git a/units/src/locktime/absolute/mod.rs b/units/src/locktime/absolute/mod.rs
index feee9be9..99672a24 100644
--- a/units/src/locktime/absolute/mod.rs
+++ b/units/src/locktime/absolute/mod.rs
@@ -407,6 +407,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for LockTime {
type Encoder<'e> = LockTimeEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
LockTimeEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus_u32().to_le_bytes(),
@@ -433,6 +434,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for LockTime {
type Decoder = LockTimeDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { LockTimeDecoder(encoding::ArrayDecoder::<4>::new()) }
}
@@ -474,6 +476,7 @@ impl fmt::Display for LockTime {
#[cfg(feature = "serde")]
impl serde::Serialize for LockTime {
+ #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
@@ -484,6 +487,7 @@ impl serde::Serialize for LockTime {
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for LockTime {
+ #[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
@@ -591,6 +595,7 @@ impl Height {
crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(Height);
impl fmt::Display for Height {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
}
@@ -631,6 +636,7 @@ impl MedianTimePast {
/// locktime: `[500_000_000, 2^32 - 1]`. Because there is a consensus rule that MTP
/// be monotonically increasing, and the MTP of the first 11 blocks exceeds `500_000_000`
/// for every real-life chain, this error typically cannot be hit in practice.
+ #[inline]
pub fn new(timestamps: [crate::BlockTime; 11]) -> Result<Self, ConversionError> {
crate::BlockMtp::new(timestamps).try_into()
}
@@ -723,6 +729,7 @@ impl MedianTimePast {
crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(MedianTimePast);
impl fmt::Display for MedianTimePast {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
}
@@ -742,9 +749,11 @@ where
}
/// Returns true if `n` is a block height i.e., less than 500,000,000.
+#[inline]
pub const fn is_block_height(n: u32) -> bool { n < LOCK_TIME_THRESHOLD }
/// Returns true if `n` is a UNIX timestamp i.e., greater than or equal to 500,000,000.
+#[inline]
pub const fn is_block_time(n: u32) -> bool { n >= LOCK_TIME_THRESHOLD }
#[cfg(feature = "arbitrary")]
diff --git a/units/src/locktime/relative/error.rs b/units/src/locktime/relative/error.rs
index dff5bead..5283ac94 100644
--- a/units/src/locktime/relative/error.rs
+++ b/units/src/locktime/relative/error.rs
@@ -34,6 +34,7 @@ impl fmt::Display for DisabledLockTimeError {
#[cfg(feature = "std")]
impl std::error::Error for DisabledLockTimeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -62,6 +63,7 @@ impl fmt::Display for IsSatisfiedByError {
#[cfg(feature = "std")]
impl std::error::Error for IsSatisfiedByError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Blocks(ref e) => Some(e),
@@ -97,6 +99,7 @@ impl fmt::Display for IsSatisfiedByHeightError {
#[cfg(feature = "std")]
impl std::error::Error for IsSatisfiedByHeightError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Satisfaction(ref e) => Some(e),
@@ -132,6 +135,7 @@ impl fmt::Display for IsSatisfiedByTimeError {
#[cfg(feature = "std")]
impl std::error::Error for IsSatisfiedByTimeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Satisfaction(ref e) => Some(e),
@@ -164,6 +168,7 @@ impl fmt::Display for TimeOverflowError {
#[cfg(feature = "std")]
impl std::error::Error for TimeOverflowError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -189,6 +194,7 @@ impl fmt::Display for InvalidHeightError {
#[cfg(feature = "std")]
impl std::error::Error for InvalidHeightError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -214,6 +220,7 @@ impl fmt::Display for InvalidTimeError {
#[cfg(feature = "std")]
impl std::error::Error for InvalidTimeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
diff --git a/units/src/locktime/relative/mod.rs b/units/src/locktime/relative/mod.rs
index 29f21380..777d3685 100644
--- a/units/src/locktime/relative/mod.rs
+++ b/units/src/locktime/relative/mod.rs
@@ -200,6 +200,7 @@ impl LockTime {
/// # Errors
///
/// If `chain_tip` as not _after_ `utxo_mined_at` i.e., if you get the args mixed up.
+ #[inline]
pub fn is_satisfied_by(
self,
chain_tip_height: BlockHeight,
@@ -368,6 +369,7 @@ impl From<LockTime> for Sequence {
#[cfg(feature = "serde")]
impl serde::Serialize for LockTime {
+ #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
@@ -378,6 +380,7 @@ impl serde::Serialize for LockTime {
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for LockTime {
+ #[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
@@ -489,6 +492,7 @@ impl From<u16> for NumberOfBlocks {
parse_int::impl_parse_str_from_int_infallible!(NumberOfBlocks, u16, from);
impl fmt::Display for NumberOfBlocks {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
}
@@ -629,6 +633,7 @@ crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(NumberOf512Seconds);
parse_int::impl_parse_str_from_int_infallible!(NumberOf512Seconds, u16, from_512_second_intervals);
impl fmt::Display for NumberOf512Seconds {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
}
diff --git a/units/src/parse_int.rs b/units/src/parse_int.rs
index b02fce97..fac1cda9 100644
--- a/units/src/parse_int.rs
+++ b/units/src/parse_int.rs
@@ -50,6 +50,7 @@ mod sealed {
/// # Errors
///
/// On error this function allocates to copy the input string into the error return.
+#[inline]
pub fn int_from_str<T: Integer>(s: &str) -> Result<T, ParseIntError> { int(s) }
/// Parses the input string as an integer returning an error carrying rich context.
@@ -57,6 +58,7 @@ pub fn int_from_str<T: Integer>(s: &str) -> Result<T, ParseIntError> { int(s) }
/// # Errors
///
/// On error the input string is moved into the error return without allocating.
+#[inline]
#[cfg(feature = "alloc")]
pub fn int_from_string<T: Integer>(s: alloc::string::String) -> Result<T, ParseIntError> { int(s) }
@@ -65,6 +67,7 @@ pub fn int_from_string<T: Integer>(s: alloc::string::String) -> Result<T, ParseI
/// # Errors
///
/// On error the input string is converted into the error return without allocating.
+#[inline]
#[cfg(feature = "alloc")]
pub fn int_from_box<T: Integer>(s: alloc::boxed::Box<str>) -> Result<T, ParseIntError> { int(s) }
@@ -112,6 +115,7 @@ macro_rules! impl_parse_str_from_int_infallible {
impl $crate::_export::_core::str::FromStr for $to {
type Err = $crate::parse_int::ParseIntError;
+ #[inline]
fn from_str(s: &str) -> $crate::_export::_core::result::Result<Self, Self::Err> {
$crate::_export::_core::convert::TryFrom::try_from(s)
}
@@ -120,6 +124,7 @@ macro_rules! impl_parse_str_from_int_infallible {
impl $crate::_export::_core::convert::TryFrom<&str> for $to {
type Error = $crate::parse_int::ParseIntError;
+ #[inline]
fn try_from(s: &str) -> $crate::_export::_core::result::Result<Self, Self::Error> {
$crate::parse_int::int_from_str::<$inner>(s).map($to::$fn)
}
@@ -129,6 +134,7 @@ macro_rules! impl_parse_str_from_int_infallible {
impl $crate::_export::_core::convert::TryFrom<alloc::string::String> for $to {
type Error = $crate::parse_int::ParseIntError;
+ #[inline]
fn try_from(
s: alloc::string::String,
) -> $crate::_export::_core::result::Result<Self, Self::Error> {
@@ -140,6 +146,7 @@ macro_rules! impl_parse_str_from_int_infallible {
impl $crate::_export::_core::convert::TryFrom<alloc::boxed::Box<str>> for $to {
type Error = $crate::parse_int::ParseIntError;
+ #[inline]
fn try_from(
s: alloc::boxed::Box<str>,
) -> $crate::_export::_core::result::Result<Self, Self::Error> {
@@ -180,6 +187,7 @@ macro_rules! impl_parse_str {
impl $crate::_export::_core::str::FromStr for $to {
type Err = $err;
+ #[inline]
fn from_str(s: &str) -> $crate::_export::_core::result::Result<Self, Self::Err> {
$inner_fn(s)
}
@@ -195,6 +203,7 @@ macro_rules! impl_tryfrom_str {
impl $crate::_export::_core::convert::TryFrom<$from> for $to {
type Error = $err;
+ #[inline]
fn try_from(s: $from) -> $crate::_export::_core::result::Result<Self, Self::Error> {
$inner_fn(s)
}
@@ -209,6 +218,7 @@ pub(crate) use impl_tryfrom_str;
/// # Errors
///
/// If the input string does not contain a prefix.
+#[inline]
pub fn hex_remove_prefix(s: &str) -> Result<&str, PrefixedHexError> {
if let Some(checked) = s.strip_prefix("0x") {
Ok(checked)
@@ -224,6 +234,7 @@ pub fn hex_remove_prefix(s: &str) -> Result<&str, PrefixedHexError> {
/// # Errors
///
/// If the input string contains a prefix.
+#[inline]
pub fn hex_check_unprefixed(s: &str) -> Result<&str, UnprefixedHexError> {
if s.starts_with("0x") || s.starts_with("0X") {
return Err(error::ContainsPrefixError::new(s).into());
@@ -247,6 +258,7 @@ macro_rules! parse_hex_for {
#[doc = "# Errors\n\nIf the input string is not a valid hex encoding of a `"]
#[doc = stringify!($int_type)]
#[doc = "`."]
+ #[inline]
pub fn $any_hex_fn(s: &str) -> Result<$int_type, ParseIntError> {
let unchecked = hex_remove_optional_prefix(s);
$uncheck_hex_fn(unchecked)
@@ -260,6 +272,7 @@ macro_rules! parse_hex_for {
#[doc = "- If the input string is not a valid hex encoding of a `"]
#[doc = stringify!($int_type)]
#[doc = "`."]
+ #[inline]
pub fn $prefix_hex_fn(s: &str) -> Result<$int_type, PrefixedHexError> {
let checked = hex_remove_prefix(s)?;
Ok($uncheck_hex_fn(checked)?)
@@ -273,6 +286,7 @@ macro_rules! parse_hex_for {
#[doc = "- If the input string is not a valid hex encoding of a `"]
#[doc = stringify!($int_type)]
#[doc = "`."]
+ #[inline]
pub fn $unprefix_hex_fn(s: &str) -> Result<$int_type, UnprefixedHexError> {
let checked = hex_check_unprefixed(s)?;
Ok($uncheck_hex_fn(checked)?)
@@ -287,6 +301,7 @@ macro_rules! parse_hex_for {
#[doc = "- If the input string is not a valid hex encoding of a `"]
#[doc = stringify!($int_type)]
#[doc = "`."]
+ #[inline]
pub fn $uncheck_hex_fn(s: &str) -> Result<$int_type, ParseIntError> {
<$int_type>::from_str_radix(s, 16).map_err(|error| ParseIntError {
input: s.into(),
@@ -328,6 +343,7 @@ parse_hex_for!(
);
/// Strips the hex prefix off `s` if one is present.
+#[inline]
pub(crate) fn hex_remove_optional_prefix(s: &str) -> &str {
if let Some(stripped) = s.strip_prefix("0x") {
stripped
@@ -381,14 +397,17 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for ParseIntError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.source) }
}
impl From<ParseIntError> for core::num::ParseIntError {
+ #[inline]
fn from(value: ParseIntError) -> Self { value.source }
}
impl AsRef<core::num::ParseIntError> for ParseIntError {
+ #[inline]
fn as_ref(&self) -> &core::num::ParseIntError { &self.source }
}
@@ -426,6 +445,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for PrefixedHexError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use PrefixedHexErrorInner as E;
@@ -437,10 +457,12 @@ pub mod error {
}
impl From<MissingPrefixError> for PrefixedHexError {
+ #[inline]
fn from(e: MissingPrefixError) -> Self { Self(PrefixedHexErrorInner::MissingPrefix(e)) }
}
impl From<ParseIntError> for PrefixedHexError {
+ #[inline]
fn from(e: ParseIntError) -> Self { Self(PrefixedHexErrorInner::ParseInt(e)) }
}
@@ -477,6 +499,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for UnprefixedHexError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use UnprefixedHexErrorInner as E;
@@ -488,10 +511,12 @@ pub mod error {
}
impl From<ContainsPrefixError> for UnprefixedHexError {
+ #[inline]
fn from(e: ContainsPrefixError) -> Self { Self(UnprefixedHexErrorInner::ContainsPrefix(e)) }
}
impl From<ParseIntError> for UnprefixedHexError {
+ #[inline]
fn from(e: ParseIntError) -> Self { Self(UnprefixedHexErrorInner::ParseInt(e)) }
}
@@ -518,6 +543,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for MissingPrefixError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
@@ -529,6 +555,7 @@ pub mod error {
impl ContainsPrefixError {
/// Constructs a new error from the string that contains the prefix.
+ #[inline]
pub(crate) fn new(hex: &str) -> Self { Self { hex: hex.into() } }
}
@@ -544,6 +571,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for ContainsPrefixError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
}
diff --git a/units/src/pow.rs b/units/src/pow.rs
index 70a936b9..116f65c7 100644
--- a/units/src/pow.rs
+++ b/units/src/pow.rs
@@ -55,6 +55,7 @@ impl CompactTarget {
///
/// - 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`.
+ #[inline]
pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError>
where
Self: Sized,
@@ -69,6 +70,7 @@ impl CompactTarget {
///
/// - If the input string contains a `0x` (or `0X`) prefix.
/// - If the input string is not a valid hex encoding of a `u32`.
+ #[inline]
pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError>
where
Self: Sized,
@@ -97,6 +99,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for CompactTarget {
type Encoder<'e> = CompactTargetEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
CompactTargetEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus().to_le_bytes(),
@@ -123,6 +126,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for CompactTarget {
type Decoder = CompactTargetDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { CompactTargetDecoder(encoding::ArrayDecoder::<4>::new()) }
}
diff --git a/units/src/result.rs b/units/src/result.rs
index 71afd0d6..f8e8e984 100644
--- a/units/src/result.rs
+++ b/units/src/result.rs
@@ -275,6 +275,7 @@ crate::internal_macros::impl_op_for_references! {
// Implement AddAssign on NumOpResults for all wrapped types that already implement AddAssign on themselves
impl<T: ops::AddAssign> ops::AddAssign<T> for NumOpResult<T> {
+ #[inline]
fn add_assign(&mut self, rhs: T) {
if let Self::Valid(ref mut lhs) = self {
*lhs += rhs;
@@ -283,6 +284,7 @@ impl<T: ops::AddAssign> ops::AddAssign<T> for NumOpResult<T> {
}
impl<T: ops::AddAssign + Copy> ops::AddAssign<Self> for NumOpResult<T> {
+ #[inline]
fn add_assign(&mut self, rhs: Self) {
match (&self, rhs) {
(Self::Valid(_), Self::Valid(rhs)) => *self += rhs,
@@ -293,6 +295,7 @@ impl<T: ops::AddAssign + Copy> ops::AddAssign<Self> for NumOpResult<T> {
// Implement SubAssign on NumOpResults for all wrapped types that already implement SubAssign on themselves
impl<T: ops::SubAssign> ops::SubAssign<T> for NumOpResult<T> {
+ #[inline]
fn sub_assign(&mut self, rhs: T) {
if let Self::Valid(ref mut lhs) = self {
*lhs -= rhs;
@@ -301,6 +304,7 @@ impl<T: ops::SubAssign> ops::SubAssign<T> for NumOpResult<T> {
}
impl<T: ops::SubAssign + Copy> ops::SubAssign<Self> for NumOpResult<T> {
+ #[inline]
fn sub_assign(&mut self, rhs: Self) {
match (&self, rhs) {
(Self::Valid(_), Self::Valid(rhs)) => *self -= rhs,
@@ -359,18 +363,23 @@ impl MathOp {
}
/// Returns `true` if this operation error'ed due to division by zero.
+ #[inline]
pub fn is_div_by_zero(self) -> bool { !self.is_overflow() }
/// Returns `true` if this operation error'ed due to addition.
+ #[inline]
pub fn is_addition(self) -> bool { self == Self::Add }
/// Returns `true` if this operation error'ed due to subtraction.
+ #[inline]
pub fn is_subtraction(self) -> bool { self == Self::Sub }
/// Returns `true` if this operation error'ed due to multiplication.
+ #[inline]
pub fn is_multiplication(self) -> bool { self == Self::Mul }
/// Returns `true` if this operation error'ed due to negation.
+ #[inline]
pub fn is_negation(self) -> bool { self == Self::Neg }
}
@@ -402,15 +411,19 @@ pub mod error {
impl NumOpError {
/// Constructs a [`NumOpError`] caused by `op`.
+ #[inline]
pub(crate) const fn while_doing(op: MathOp) -> Self { Self(op) }
/// Returns `true` if this operation error'ed due to overflow.
+ #[inline]
pub fn is_overflow(self) -> bool { self.0.is_overflow() }
/// Returns `true` if this operation error'ed due to division by zero.
+ #[inline]
pub fn is_div_by_zero(self) -> bool { self.0.is_div_by_zero() }
/// Returns the [`MathOp`] that caused this error.
+ #[inline]
pub fn operation(self) -> MathOp { self.0 }
}
@@ -426,6 +439,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for NumOpError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}
}
diff --git a/units/src/sequence.rs b/units/src/sequence.rs
index d683d0c9..130a695d 100644
--- a/units/src/sequence.rs
+++ b/units/src/sequence.rs
@@ -268,6 +268,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for Sequence {
type Encoder<'e> = SequenceEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
SequenceEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus_u32().to_le_bytes(),
@@ -294,6 +295,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for Sequence {
type Decoder = SequenceDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { SequenceDecoder(encoding::ArrayDecoder::<4>::new()) }
}
@@ -327,6 +329,7 @@ pub mod error {
#[cfg(feature = "encoding")]
#[cfg(feature = "std")]
impl std::error::Error for SequenceDecoderError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
}
diff --git a/units/src/time.rs b/units/src/time.rs
index 917b8d82..0305d936 100644
--- a/units/src/time.rs
+++ b/units/src/time.rs
@@ -79,6 +79,7 @@ impl BlockTime {
crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(BlockTime, to_u32);
impl fmt::Display for BlockTime {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.to_u32(), f) }
}
@@ -126,6 +127,7 @@ encoding::encoder_newtype_exact! {
#[cfg(feature = "encoding")]
impl encoding::Encodable for BlockTime {
type Encoder<'e> = BlockTimeEncoder<'e>;
+ #[inline]
fn encoder(&self) -> Self::Encoder<'_> {
BlockTimeEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_u32().to_le_bytes(),
@@ -152,6 +154,7 @@ crate::decoder_newtype! {
#[cfg(feature = "encoding")]
impl encoding::Decodable for BlockTime {
type Decoder = BlockTimeDecoder;
+ #[inline]
fn decoder() -> Self::Decoder { BlockTimeDecoder(encoding::ArrayDecoder::<4>::new()) }
}
@@ -185,6 +188,7 @@ pub mod error {
#[cfg(feature = "encoding")]
#[cfg(feature = "std")]
impl std::error::Error for BlockTimeDecoderError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
}
diff --git a/units/src/weight.rs b/units/src/weight.rs
index e26ba601..f135ac6d 100644
--- a/units/src/weight.rs
+++ b/units/src/weight.rs
@@ -26,11 +26,13 @@ mod encapsulate {
impl Weight {
/// Constructs a new [`Weight`] from weight units.
+ #[inline]
pub const fn from_wu(wu: u64) -> Self { Self(wu) }
/// Returns raw weight units.
///
/// Can be used instead of `into()` to avoid inference issues.
+ #[inline]
pub const fn to_wu(self) -> u64 { self.0 }
}
}
@@ -61,6 +63,7 @@ impl Weight {
pub const MIN_TRANSACTION: Self = Self::from_wu(Self::WITNESS_SCALE_FACTOR * 60);
/// Constructs a new [`Weight`] from kilo weight units returning [`None`] if an overflow occurred.
+ #[inline]
pub const fn from_kwu(wu: u64) -> Option<Self> {
// No `map()` in const context.
match wu.checked_mul(1000) {
@@ -70,6 +73,7 @@ impl Weight {
}
/// Constructs a new [`Weight`] from virtual bytes, returning [`None`] if an overflow occurred.
+ #[inline]
pub const fn from_vb(vb: u64) -> Option<Self> {
// No `map()` in const context.
match vb.checked_mul(Self::WITNESS_SCALE_FACTOR) {
@@ -92,6 +96,7 @@ impl Weight {
}
/// Constructs a new [`Weight`] from virtual bytes without an overflow check.
+ #[inline]
pub const fn from_vb_unchecked(vb: u64) -> Self {
Self::from_wu(vb * Self::WITNESS_SCALE_FACTOR)
}
@@ -135,20 +140,25 @@ impl Weight {
}
/// Converts to kilo weight units rounding down.
+ #[inline]
pub const fn to_kwu_floor(self) -> u64 { self.to_wu() / 1000 }
/// Converts to kilo weight units rounding up.
+ #[inline]
pub const fn to_kwu_ceil(self) -> u64 { self.to_wu().div_ceil(1_000) }
/// Converts to vB rounding down.
+ #[inline]
pub const fn to_vbytes_floor(self) -> u64 { self.to_wu() / Self::WITNESS_SCALE_FACTOR }
/// Converts to vB rounding up.
+ #[inline]
pub const fn to_vbytes_ceil(self) -> u64 { self.to_wu().div_ceil(Self::WITNESS_SCALE_FACTOR) }
/// Checked addition.
///
/// Computes `self + rhs` returning [`None`] if an overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -161,6 +171,7 @@ impl Weight {
/// Checked subtraction.
///
/// Computes `self - rhs` returning [`None`] if an overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
// No `map()` in const context.
@@ -173,6 +184,7 @@ impl Weight {
/// Checked multiplication.
///
/// Computes `self * rhs` returning [`None`] if an overflow occurred.
+ #[inline]
#[must_use]
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -185,6 +197,7 @@ impl Weight {
/// Checked division.
///
/// Computes `self / rhs` returning [`None`] if `rhs == 0`.
+ #[inline]
#[must_use]
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
// No `map()` in const context.
@@ -199,6 +212,7 @@ impl Weight {
/// Computes the absolute fee amount for a given [`FeeRate`] at this weight. When the resulting
/// fee is a non-integer amount, the amount is rounded up, ensuring that the transaction fee is
/// enough instead of falling short if rounded down.
+ #[inline]
pub const fn mul_by_fee_rate(self, fee_rate: FeeRate) -> NumOpResult<Amount> {
fee_rate.mul_by_weight(self)
}
@@ -218,6 +232,7 @@ impl fmt::Display for Weight {
}
impl From<Weight> for u64 {
+ #[inline]
fn from(value: Weight) -> Self { value.to_wu() }
}
@@ -273,18 +288,22 @@ crate::internal_macros::impl_add_assign!(Weight);
crate::internal_macros::impl_sub_assign!(Weight);
impl ops::MulAssign<u64> for Weight {
+ #[inline]
fn mul_assign(&mut self, rhs: u64) { *self = Self::from_wu(self.to_wu() * rhs); }
}
impl ops::DivAssign<u64> for Weight {
+ #[inline]
fn div_assign(&mut self, rhs: u64) { *self = Self::from_wu(self.to_wu() / rhs); }
}
impl ops::RemAssign<u64> for Weight {
+ #[inline]
fn rem_assign(&mut self, rhs: u64) { *self = Self::from_wu(self.to_wu() % rhs); }
}
impl core::iter::Sum for Weight {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
@@ -294,6 +313,7 @@ impl core::iter::Sum for Weight {
}
impl<'a> core::iter::Sum<&'a Self> for Weight {
+ #[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.