Merge rust-bitcoin/rust-bitcoin#4143: primitives: Inline small functions

b656d7a16c Inline small functions (Jamil Lambert, PhD)

Pull request description:

  Functions that fit the below criteria should be inline:

  > Basically, if a function jut delegates into another function and passing through arguments, it should be inline. Also when doing assignment of `u32` or similarly trivial operation. Also if it checks the validity of argument(s) and then performs something simple (like a call to `_unchecked`).

  _Originally posted by Kixunil in https://github.com/rust-bitcoin/rust-bitcoin/pull/4099#discussion_r1966156399_

  Add `#[inline]` to all functions in `primitives` that fit the criteria.

ACKs for top commit:
  tcharding:
    ACK b656d7a16c
  apoelstra:
    ACK b656d7a16c2d0cdd6d8a94fffeac842ffc0fabf4; successfully ran local tests

Tree-SHA512: 0059aa25252e634e55482b201a9414d19a01435fea801a20dc38b4b701a52f4a14565a1cfb0ff4ed7a771a25629eb192fd69cb4ee81e78f6a0ef79d56db0ef5b
This commit is contained in:
merge-script 2025-03-04 14:35:14 +00:00
commit 95c012ee53
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
8 changed files with 69 additions and 0 deletions

View File

@ -70,6 +70,7 @@ where
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl Block<Unchecked> { impl Block<Unchecked> {
/// Constructs a new `Block` without doing any validation. /// Constructs a new `Block` without doing any validation.
#[inline]
pub fn new_unchecked(header: Header, transactions: Vec<Transaction>) -> Block<Unchecked> { pub fn new_unchecked(header: Header, transactions: Vec<Transaction>) -> Block<Unchecked> {
Block { header, transactions, witness_root: None, marker: PhantomData::<Unchecked> } Block { header, transactions, witness_root: None, marker: PhantomData::<Unchecked> }
} }
@ -78,6 +79,7 @@ impl Block<Unchecked> {
/// ///
/// You should only use this function if you trust the block i.e., it comes from a trusted node. /// You should only use this function if you trust the block i.e., it comes from a trusted node.
#[must_use] #[must_use]
#[inline]
pub fn assume_checked(self, witness_root: Option<WitnessMerkleNode>) -> Block<Checked> { pub fn assume_checked(self, witness_root: Option<WitnessMerkleNode>) -> Block<Checked> {
Block { Block {
header: self.header, header: self.header,
@ -88,37 +90,44 @@ impl Block<Unchecked> {
} }
/// Decomposes block into its constituent parts. /// Decomposes block into its constituent parts.
#[inline]
pub fn into_parts(self) -> (Header, Vec<Transaction>) { (self.header, self.transactions) } pub fn into_parts(self) -> (Header, Vec<Transaction>) { (self.header, self.transactions) }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl Block<Checked> { impl Block<Checked> {
/// Gets a reference to the block header. /// Gets a reference to the block header.
#[inline]
pub fn header(&self) -> &Header { &self.header } pub fn header(&self) -> &Header { &self.header }
/// Gets a reference to the block's list of transactions. /// Gets a reference to the block's list of transactions.
#[inline]
pub fn transactions(&self) -> &[Transaction] { &self.transactions } pub fn transactions(&self) -> &[Transaction] { &self.transactions }
/// Returns the cached witness root if one is present. /// Returns the cached witness root if one is present.
/// ///
/// It is assumed that a block will have the witness root calculated and cached as part of the /// It is assumed that a block will have the witness root calculated and cached as part of the
/// validation process. /// validation process.
#[inline]
pub fn cached_witness_root(&self) -> Option<WitnessMerkleNode> { self.witness_root } pub fn cached_witness_root(&self) -> Option<WitnessMerkleNode> { self.witness_root }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl<V: Validation> Block<V> { impl<V: Validation> Block<V> {
/// Returns the block hash. /// Returns the block hash.
#[inline]
pub fn block_hash(&self) -> BlockHash { self.header.block_hash() } pub fn block_hash(&self) -> BlockHash { self.header.block_hash() }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<Block> for BlockHash { impl From<Block> for BlockHash {
#[inline]
fn from(block: Block) -> BlockHash { block.block_hash() } fn from(block: Block) -> BlockHash { block.block_hash() }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<&Block> for BlockHash { impl From<&Block> for BlockHash {
#[inline]
fn from(block: &Block) -> BlockHash { block.block_hash() } fn from(block: &Block) -> BlockHash { block.block_hash() }
} }
@ -212,10 +221,12 @@ impl fmt::Debug for Header {
} }
impl From<Header> for BlockHash { impl From<Header> for BlockHash {
#[inline]
fn from(header: Header) -> BlockHash { header.block_hash() } fn from(header: Header) -> BlockHash { header.block_hash() }
} }
impl From<&Header> for BlockHash { impl From<&Header> for BlockHash {
#[inline]
fn from(header: &Header) -> BlockHash { header.block_hash() } fn from(header: &Header) -> BlockHash { header.block_hash() }
} }
@ -263,6 +274,7 @@ impl Version {
/// Returns the inner `i32` value. /// Returns the inner `i32` value.
/// ///
/// This is the data type used in consensus code in Bitcoin Core. /// This is the data type used in consensus code in Bitcoin Core.
#[inline]
pub fn to_consensus(self) -> i32 { self.0 } pub fn to_consensus(self) -> i32 { self.0 }
/// Checks whether the version number is signalling a soft fork at the given bit. /// Checks whether the version number is signalling a soft fork at the given bit.
@ -286,6 +298,7 @@ impl Version {
} }
impl Default for Version { impl Default for Version {
#[inline]
fn default() -> Version { Self::NO_SOFT_FORK_SIGNALLING } fn default() -> Version { Self::NO_SOFT_FORK_SIGNALLING }
} }

View File

@ -102,6 +102,7 @@ impl LockTime {
/// ///
/// # Ok::<_, units::parse::PrefixedHexError>(()) /// # Ok::<_, units::parse::PrefixedHexError>(())
/// ``` /// ```
#[inline]
pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError> { pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError> {
let lock_time = parse::hex_u32_prefixed(s)?; let lock_time = parse::hex_u32_prefixed(s)?;
Ok(Self::from_consensus(lock_time)) Ok(Self::from_consensus(lock_time))
@ -119,6 +120,7 @@ impl LockTime {
/// ///
/// # Ok::<_, units::parse::UnprefixedHexError>(()) /// # Ok::<_, units::parse::UnprefixedHexError>(())
/// ``` /// ```
#[inline]
pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError> { pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError> {
let lock_time = parse::hex_u32_unprefixed(s)?; let lock_time = parse::hex_u32_unprefixed(s)?;
Ok(Self::from_consensus(lock_time)) Ok(Self::from_consensus(lock_time))
@ -320,6 +322,7 @@ impl From<Time> for LockTime {
} }
impl fmt::Debug for LockTime { impl fmt::Debug for LockTime {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use LockTime::*; use LockTime::*;

View File

@ -89,6 +89,7 @@ impl LockTime {
/// ///
/// # Ok::<_, bitcoin_primitives::relative::DisabledLockTimeError>(()) /// # Ok::<_, bitcoin_primitives::relative::DisabledLockTimeError>(())
/// ``` /// ```
#[inline]
pub fn from_consensus(n: u32) -> Result<Self, DisabledLockTimeError> { pub fn from_consensus(n: u32) -> Result<Self, DisabledLockTimeError> {
let sequence = crate::Sequence::from_consensus(n); let sequence = crate::Sequence::from_consensus(n);
sequence.to_relative_lock_time().ok_or(DisabledLockTimeError(n)) sequence.to_relative_lock_time().ok_or(DisabledLockTimeError(n))
@ -370,12 +371,14 @@ impl fmt::Display for LockTime {
impl convert::TryFrom<Sequence> for LockTime { impl convert::TryFrom<Sequence> for LockTime {
type Error = DisabledLockTimeError; type Error = DisabledLockTimeError;
#[inline]
fn try_from(seq: Sequence) -> Result<LockTime, DisabledLockTimeError> { fn try_from(seq: Sequence) -> Result<LockTime, DisabledLockTimeError> {
LockTime::from_sequence(seq) LockTime::from_sequence(seq)
} }
} }
impl From<LockTime> for Sequence { impl From<LockTime> for Sequence {
#[inline]
fn from(lt: LockTime) -> Sequence { lt.to_sequence() } fn from(lt: LockTime) -> Sequence { lt.to_sequence() }
} }
@ -387,10 +390,12 @@ pub struct DisabledLockTimeError(u32);
impl DisabledLockTimeError { impl DisabledLockTimeError {
/// Accessor for the `u32` whose "disable" flag was set, preventing /// Accessor for the `u32` whose "disable" flag was set, preventing
/// it from being parsed as a relative locktime. /// it from being parsed as a relative locktime.
#[inline]
pub fn disabled_locktime_value(&self) -> u32 { self.0 } pub fn disabled_locktime_value(&self) -> u32 { self.0 }
} }
impl fmt::Display for DisabledLockTimeError { impl fmt::Display for DisabledLockTimeError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "lock time 0x{:08x} has disable flag set", self.0) write!(f, "lock time 0x{:08x} has disable flag set", self.0)
} }
@ -417,6 +422,7 @@ impl IncompatibleHeightError {
} }
impl fmt::Display for IncompatibleHeightError { impl fmt::Display for IncompatibleHeightError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
@ -447,6 +453,7 @@ impl IncompatibleTimeError {
} }
impl fmt::Display for IncompatibleTimeError { impl fmt::Display for IncompatibleTimeError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,

View File

@ -440,6 +440,7 @@ impl From<u8> for Opcode {
} }
impl fmt::Debug for Opcode { impl fmt::Debug for Opcode {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fmt::Display::fmt(self, f) } fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fmt::Display::fmt(self, f) }
} }

View File

@ -24,9 +24,11 @@ pub struct CompactTarget(u32);
impl CompactTarget { impl CompactTarget {
/// Constructs a new [`CompactTarget`] from a consensus encoded `u32`. /// Constructs a new [`CompactTarget`] from a consensus encoded `u32`.
#[inline]
pub fn from_consensus(bits: u32) -> Self { Self(bits) } pub fn from_consensus(bits: u32) -> Self { Self(bits) }
/// Returns the consensus encoded `u32` representation of this [`CompactTarget`]. /// Returns the consensus encoded `u32` representation of this [`CompactTarget`].
#[inline]
pub fn to_consensus(self) -> u32 { self.0 } pub fn to_consensus(self) -> u32 { self.0 }
} }

View File

@ -124,12 +124,14 @@ impl Sequence {
} }
/// Constructs a new `Sequence` from a prefixed hex string. /// Constructs a new `Sequence` from a prefixed hex string.
#[inline]
pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError> { pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError> {
let lock_time = parse::hex_u32_prefixed(s)?; let lock_time = parse::hex_u32_prefixed(s)?;
Ok(Self::from_consensus(lock_time)) Ok(Self::from_consensus(lock_time))
} }
/// Constructs a new `Sequence` from an unprefixed hex string. /// Constructs a new `Sequence` from an unprefixed hex string.
#[inline]
pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError> { pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError> {
let lock_time = parse::hex_u32_unprefixed(s)?; let lock_time = parse::hex_u32_unprefixed(s)?;
Ok(Self::from_consensus(lock_time)) Ok(Self::from_consensus(lock_time))
@ -203,23 +205,28 @@ impl Sequence {
/// Returns the low 16 bits from sequence number. /// Returns the low 16 bits from sequence number.
/// ///
/// BIP-68 only uses the low 16 bits for relative lock value. /// BIP-68 only uses the low 16 bits for relative lock value.
#[inline]
fn low_u16(&self) -> u16 { self.0 as u16 } fn low_u16(&self) -> u16 { self.0 as u16 }
} }
impl Default for Sequence { impl Default for Sequence {
/// The default value of sequence is 0xffffffff. /// The default value of sequence is 0xffffffff.
#[inline]
fn default() -> Self { Sequence::MAX } fn default() -> Self { Sequence::MAX }
} }
impl From<Sequence> for u32 { impl From<Sequence> for u32 {
#[inline]
fn from(sequence: Sequence) -> u32 { sequence.0 } fn from(sequence: Sequence) -> u32 { sequence.0 }
} }
impl fmt::Display for Sequence { impl fmt::Display for Sequence {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
} }
impl fmt::LowerHex for Sequence { impl fmt::LowerHex for Sequence {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
@ -228,10 +235,12 @@ internals::impl_to_hex_from_lower_hex!(Sequence, |sequence: &Sequence| {
}); });
impl fmt::UpperHex for Sequence { impl fmt::UpperHex for Sequence {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
} }
impl fmt::Debug for Sequence { impl fmt::Debug for Sequence {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// 10 because its 8 digits + 2 for the '0x' // 10 because its 8 digits + 2 for the '0x'
write!(f, "Sequence({:#010x})", self.0) write!(f, "Sequence({:#010x})", self.0)

View File

@ -115,15 +115,19 @@ impl Transaction {
pub const MAX_STANDARD_WEIGHT: Weight = Weight::from_wu(400_000); pub const MAX_STANDARD_WEIGHT: Weight = Weight::from_wu(400_000);
/// Returns a reference to the transaction inputs. /// Returns a reference to the transaction inputs.
#[inline]
pub fn inputs(&self) -> &[TxIn] { &self.input } pub fn inputs(&self) -> &[TxIn] { &self.input }
/// Returns a mutable reference to the transaction inputs. /// Returns a mutable reference to the transaction inputs.
#[inline]
pub fn inputs_mut(&mut self) -> &mut [TxIn] { &mut self.input } pub fn inputs_mut(&mut self) -> &mut [TxIn] { &mut self.input }
/// Returns a reference to the transaction outputs. /// Returns a reference to the transaction outputs.
#[inline]
pub fn outputs(&self) -> &[TxOut] { &self.output } pub fn outputs(&self) -> &[TxOut] { &self.output }
/// Returns a mutable reference to the transaction outputs. /// Returns a mutable reference to the transaction outputs.
#[inline]
pub fn outputs_mut(&mut self) -> &mut [TxOut] { &mut self.output } pub fn outputs_mut(&mut self) -> &mut [TxOut] { &mut self.output }
/// Computes a "normalized TXID" which does not include any signatures. /// Computes a "normalized TXID" which does not include any signatures.
@ -155,6 +159,7 @@ impl Transaction {
/// witness fields themselves). For non-SegWit transactions which do not have any SegWit data, /// witness fields themselves). For non-SegWit transactions which do not have any SegWit data,
/// this will be equal to [`Transaction::compute_wtxid()`]. /// this will be equal to [`Transaction::compute_wtxid()`].
#[doc(alias = "txid")] #[doc(alias = "txid")]
#[inline]
pub fn compute_txid(&self) -> Txid { pub fn compute_txid(&self) -> Txid {
let hash = hash_transaction(self, false); let hash = hash_transaction(self, false);
Txid::from_byte_array(hash.to_byte_array()) Txid::from_byte_array(hash.to_byte_array())
@ -166,6 +171,7 @@ impl Transaction {
/// witness fields themselves). For non-SegWit transactions which do not have any SegWit data, /// witness fields themselves). For non-SegWit transactions which do not have any SegWit data,
/// this will be equal to [`Transaction::compute_txid()`]. /// this will be equal to [`Transaction::compute_txid()`].
#[doc(alias = "wtxid")] #[doc(alias = "wtxid")]
#[inline]
pub fn compute_wtxid(&self) -> Wtxid { pub fn compute_wtxid(&self) -> Wtxid {
let hash = hash_transaction(self, self.uses_segwit_serialization()); let hash = hash_transaction(self, self.uses_segwit_serialization());
Wtxid::from_byte_array(hash.to_byte_array()) Wtxid::from_byte_array(hash.to_byte_array())
@ -173,6 +179,7 @@ impl Transaction {
/// Returns whether or not to serialize transaction as specified in BIP-144. /// Returns whether or not to serialize transaction as specified in BIP-144.
// This is duplicated in `bitcoin`, if you change it please do so in both places. // This is duplicated in `bitcoin`, if you change it please do so in both places.
#[inline]
fn uses_segwit_serialization(&self) -> bool { fn uses_segwit_serialization(&self) -> bool {
if self.input.iter().any(|input| !input.witness.is_empty()) { if self.input.iter().any(|input| !input.witness.is_empty()) {
return true; return true;
@ -185,6 +192,7 @@ impl Transaction {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl cmp::PartialOrd for Transaction { impl cmp::PartialOrd for Transaction {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) } fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
} }
@ -201,21 +209,25 @@ impl cmp::Ord for Transaction {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<Transaction> for Txid { impl From<Transaction> for Txid {
#[inline]
fn from(tx: Transaction) -> Txid { tx.compute_txid() } fn from(tx: Transaction) -> Txid { tx.compute_txid() }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<&Transaction> for Txid { impl From<&Transaction> for Txid {
#[inline]
fn from(tx: &Transaction) -> Txid { tx.compute_txid() } fn from(tx: &Transaction) -> Txid { tx.compute_txid() }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<Transaction> for Wtxid { impl From<Transaction> for Wtxid {
#[inline]
fn from(tx: Transaction) -> Wtxid { tx.compute_wtxid() } fn from(tx: Transaction) -> Wtxid { tx.compute_wtxid() }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<&Transaction> for Wtxid { impl From<&Transaction> for Wtxid {
#[inline]
fn from(tx: &Transaction) -> Wtxid { tx.compute_wtxid() } fn from(tx: &Transaction) -> Wtxid { tx.compute_wtxid() }
} }
@ -377,6 +389,7 @@ impl OutPoint {
} }
impl fmt::Display for OutPoint { impl fmt::Display for OutPoint {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}", self.txid, self.vout) write!(f, "{}:{}", self.txid, self.vout)
} }
@ -439,6 +452,7 @@ pub enum ParseOutPointError {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<Infallible> for ParseOutPointError { impl From<Infallible> for ParseOutPointError {
#[inline]
fn from(never: Infallible) -> Self { match never {} } fn from(never: Infallible) -> Self { match never {} }
} }
@ -553,10 +567,12 @@ impl Version {
} }
impl fmt::Display for Version { impl fmt::Display for Version {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
} }
impl From<Version> for u32 { impl From<Version> for u32 {
#[inline]
fn from(version: Version) -> Self { version.0 } fn from(version: Version) -> Self { version.0 }
} }

View File

@ -99,18 +99,22 @@ impl Witness {
} }
/// Convenience method to create an array of byte-arrays from this witness. /// Convenience method to create an array of byte-arrays from this witness.
#[inline]
pub fn to_vec(&self) -> Vec<Vec<u8>> { self.iter().map(|s| s.to_vec()).collect() } pub fn to_vec(&self) -> Vec<Vec<u8>> { self.iter().map(|s| s.to_vec()).collect() }
/// Returns `true` if the witness contains no element. /// Returns `true` if the witness contains no element.
#[inline]
pub fn is_empty(&self) -> bool { self.witness_elements == 0 } pub fn is_empty(&self) -> bool { self.witness_elements == 0 }
/// Returns a struct implementing [`Iterator`]. /// Returns a struct implementing [`Iterator`].
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[inline]
pub fn iter(&self) -> Iter { pub fn iter(&self) -> Iter {
Iter { inner: self.content.as_slice(), indices_start: self.indices_start, current_index: 0 } Iter { inner: self.content.as_slice(), indices_start: self.indices_start, current_index: 0 }
} }
/// Returns the number of elements this witness holds. /// Returns the number of elements this witness holds.
#[inline]
pub fn len(&self) -> usize { self.witness_elements } pub fn len(&self) -> usize { self.witness_elements }
/// Returns the number of bytes this witness contributes to a transactions total size. /// Returns the number of bytes this witness contributes to a transactions total size.
@ -130,6 +134,7 @@ impl Witness {
} }
/// Clear the witness. /// Clear the witness.
#[inline]
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.content.clear(); self.content.clear();
self.witness_elements = 0; self.witness_elements = 0;
@ -137,6 +142,7 @@ impl Witness {
} }
/// Push a new element on the witness, requires an allocation. /// Push a new element on the witness, requires an allocation.
#[inline]
pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) { pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) {
self.push_slice(new_element.as_ref()); self.push_slice(new_element.as_ref());
} }
@ -178,6 +184,7 @@ impl Witness {
} }
/// Returns the last element in the witness, if any. /// Returns the last element in the witness, if any.
#[inline]
pub fn last(&self) -> Option<&[u8]> { pub fn last(&self) -> Option<&[u8]> {
if self.witness_elements == 0 { if self.witness_elements == 0 {
None None
@ -187,6 +194,7 @@ impl Witness {
} }
/// Returns the second-to-last element in the witness, if any. /// Returns the second-to-last element in the witness, if any.
#[inline]
pub fn second_to_last(&self) -> Option<&[u8]> { pub fn second_to_last(&self) -> Option<&[u8]> {
if self.witness_elements <= 1 { if self.witness_elements <= 1 {
None None
@ -196,6 +204,7 @@ impl Witness {
} }
/// Returns the third-to-last element in the witness, if any. /// Returns the third-to-last element in the witness, if any.
#[inline]
pub fn third_to_last(&self) -> Option<&[u8]> { pub fn third_to_last(&self) -> Option<&[u8]> {
if self.witness_elements <= 2 { if self.witness_elements <= 2 {
None None
@ -205,6 +214,7 @@ impl Witness {
} }
/// Return the nth element in the witness, if any /// Return the nth element in the witness, if any
#[inline]
pub fn nth(&self, index: usize) -> Option<&[u8]> { pub fn nth(&self, index: usize) -> Option<&[u8]> {
let pos = decode_cursor(&self.content, self.indices_start, index)?; let pos = decode_cursor(&self.content, self.indices_start, index)?;
self.element_at(pos) self.element_at(pos)
@ -264,6 +274,7 @@ pub struct Iter<'a> {
impl Index<usize> for Witness { impl Index<usize> for Witness {
type Output = [u8]; type Output = [u8];
#[inline]
fn index(&self, index: usize) -> &Self::Output { self.nth(index).expect("out of bounds") } fn index(&self, index: usize) -> &Self::Output { self.nth(index).expect("out of bounds") }
} }
@ -281,6 +292,7 @@ impl<'a> Iterator for Iter<'a> {
Some(&slice[..end]) Some(&slice[..end])
} }
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
let total_count = (self.inner.len() - self.indices_start) / 4; let total_count = (self.inner.len() - self.indices_start) / 4;
let remaining = total_count - self.current_index; let remaining = total_count - self.current_index;
@ -294,6 +306,7 @@ impl<'a> IntoIterator for &'a Witness {
type IntoIter = Iter<'a>; type IntoIter = Iter<'a>;
type Item = &'a [u8]; type Item = &'a [u8];
#[inline]
fn into_iter(self) -> Self::IntoIter { self.iter() } fn into_iter(self) -> Self::IntoIter { self.iter() }
} }
@ -381,22 +394,27 @@ impl<'de> serde::Deserialize<'de> for Witness {
} }
impl From<Vec<Vec<u8>>> for Witness { impl From<Vec<Vec<u8>>> for Witness {
#[inline]
fn from(vec: Vec<Vec<u8>>) -> Self { Witness::from_slice(&vec) } fn from(vec: Vec<Vec<u8>>) -> Self { Witness::from_slice(&vec) }
} }
impl From<&[&[u8]]> for Witness { impl From<&[&[u8]]> for Witness {
#[inline]
fn from(slice: &[&[u8]]) -> Self { Witness::from_slice(slice) } fn from(slice: &[&[u8]]) -> Self { Witness::from_slice(slice) }
} }
impl From<&[Vec<u8>]> for Witness { impl From<&[Vec<u8>]> for Witness {
#[inline]
fn from(slice: &[Vec<u8>]) -> Self { Witness::from_slice(slice) } fn from(slice: &[Vec<u8>]) -> Self { Witness::from_slice(slice) }
} }
impl From<Vec<&[u8]>> for Witness { impl From<Vec<&[u8]>> for Witness {
#[inline]
fn from(vec: Vec<&[u8]>) -> Self { Witness::from_slice(&vec) } fn from(vec: Vec<&[u8]>) -> Self { Witness::from_slice(&vec) }
} }
impl Default for Witness { impl Default for Witness {
#[inline]
fn default() -> Self { Self::new() } fn default() -> Self { Self::new() }
} }