diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index 46bffc5fd..f30063cd7 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -1,74 +1,44 @@ // SPDX-License-Identifier: CC0-1.0 //! Public macros. +//! +//! - [`sha256t_tag`](crate::sha256t_tag) +//! - [`hash_newtype`](crate::hash_newtype) -/// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`. -#[doc(hidden)] +/// Macro used to define a tag. +/// +/// Defines new struct and implements `Tag` for it. +/// +/// The syntax is: +/// +/// ``` +/// # use bitcoin_hashes::sha256t_tag; +/// sha256t_tag! { +/// /// Optional documentation details here. +/// /// Summary is always generated. +/// pub struct FooTag = hash_str("foo"); +/// } +/// ``` +/// +/// The `hash_str` marker says the midstate should be generated by hashing the supplied string in a +/// way described in BIP-341. Alternatively, you can supply `hash_bytes` to hash raw bytes. If you +/// have the midstate already pre-computed and prefer **compiler** performance to readability you +/// may use `raw(MIDSTATE_BYTES, HASHED_BYTES_LENGTH)` instead, note that HASHED_BYTES_LENGTH must +/// be a multiple of 64. #[macro_export] -macro_rules! hex_fmt_impl( - ($reverse:expr, $len:expr, $ty:ident) => ( - $crate::hex_fmt_impl!($reverse, $len, $ty, ); - ); - ($reverse:expr, $len:expr, $ty:ident, $($gen:ident: $gent:ident),*) => ( - impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> { +macro_rules! sha256t_tag { + ($(#[$($tag_attr:tt)*])* $tag_vis:vis struct $tag:ident = $constructor:tt($($tag_value:tt)+);) => { + $crate::sha256t_tag_struct!($tag_vis, $tag, stringify!($hash_name), $(#[$($tag_attr)*])*); + + impl $crate::sha256t::Tag for $tag { #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - if $reverse { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Lower) - } else { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Lower) - } + fn engine() -> $crate::sha256::HashEngine { + const MIDSTATE: $crate::sha256::Midstate = $crate::sha256t_tag_constructor!($constructor, $($tag_value)+); + $crate::sha256::HashEngine::from_midstate(MIDSTATE) } } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::UpperHex for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - if $reverse { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Upper) - } else { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Upper) - } - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::Display for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - $crate::_export::_core::fmt::LowerHex::fmt(&self, f) - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - write!(f, "{}", self) - } - } - ); -); - -/// Adds slicing traits implementations to a given type `$ty` -#[doc(hidden)] -#[macro_export] -macro_rules! borrow_slice_impl( - ($ty:ident) => ( - $crate::borrow_slice_impl!($ty, ); - ); - ($ty:ident, $($gen:ident: $gent:ident),*) => ( - impl<$($gen: $gent),*> $crate::_export::_core::borrow::Borrow<[u8]> for $ty<$($gen),*> { - fn borrow(&self) -> &[u8] { - self.as_byte_array() - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { - fn as_ref(&self) -> &[u8] { - self.as_byte_array() - } - } - ) -); + } +} /// Creates a new newtype around a [`Hash`] type. /// @@ -245,6 +215,74 @@ macro_rules! hash_newtype { }; } +/// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`. +#[doc(hidden)] +#[macro_export] +macro_rules! hex_fmt_impl( + ($reverse:expr, $len:expr, $ty:ident) => ( + $crate::hex_fmt_impl!($reverse, $len, $ty, ); + ); + ($reverse:expr, $len:expr, $ty:ident, $($gen:ident: $gent:ident),*) => ( + impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> { + #[inline] + fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { + if $reverse { + $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Lower) + } else { + $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Lower) + } + } + } + + impl<$($gen: $gent),*> $crate::_export::_core::fmt::UpperHex for $ty<$($gen),*> { + #[inline] + fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { + if $reverse { + $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Upper) + } else { + $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Upper) + } + } + } + + impl<$($gen: $gent),*> $crate::_export::_core::fmt::Display for $ty<$($gen),*> { + #[inline] + fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { + $crate::_export::_core::fmt::LowerHex::fmt(&self, f) + } + } + + impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> { + #[inline] + fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { + write!(f, "{}", self) + } + } + ); +); + +/// Adds slicing traits implementations to a given type `$ty` +#[doc(hidden)] +#[macro_export] +macro_rules! borrow_slice_impl( + ($ty:ident) => ( + $crate::borrow_slice_impl!($ty, ); + ); + ($ty:ident, $($gen:ident: $gent:ident),*) => ( + impl<$($gen: $gent),*> $crate::_export::_core::borrow::Borrow<[u8]> for $ty<$($gen),*> { + fn borrow(&self) -> &[u8] { + self.as_byte_array() + } + } + + impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { + fn as_ref(&self) -> &[u8] { + self.as_byte_array() + } + } + ) +); + // Generates the struct only (no impls) // // This is a separate macro to make it more readable and have a separate interface that allows for diff --git a/hashes/src/sha256t.rs b/hashes/src/sha256t.rs index f68991780..8e6faab73 100644 --- a/hashes/src/sha256t.rs +++ b/hashes/src/sha256t.rs @@ -141,41 +141,6 @@ where Hash::from_byte_array(sha256::Hash::from_engine(e).to_byte_array()) } -/// Macro used to define a tag. -/// -/// Defines new struct and implements `Tag` for it. -/// -/// The syntax is: -/// -/// ``` -/// # use bitcoin_hashes::sha256t_tag; -/// sha256t_tag! { -/// /// Optional documentation details here. -/// /// Summary is always generated. -/// pub struct FooTag = hash_str("foo"); -/// } -/// ``` -/// -/// The `hash_str` marker says the midstate should be generated by hashing the supplied string in a -/// way described in BIP-341. Alternatively, you can supply `hash_bytes` to hash raw bytes. If you -/// have the midstate already pre-computed and prefer **compiler** performance to readability you -/// may use `raw(MIDSTATE_BYTES, HASHED_BYTES_LENGTH)` instead, note that HASHED_BYTES_LENGTH must -/// be a multiple of 64. -#[macro_export] -macro_rules! sha256t_tag { - ($(#[$($tag_attr:tt)*])* $tag_vis:vis struct $tag:ident = $constructor:tt($($tag_value:tt)+);) => { - $crate::sha256t_tag_struct!($tag_vis, $tag, stringify!($hash_name), $(#[$($tag_attr)*])*); - - impl $crate::sha256t::Tag for $tag { - #[inline] - fn engine() -> $crate::sha256::HashEngine { - const MIDSTATE: $crate::sha256::Midstate = $crate::sha256t_tag_constructor!($constructor, $($tag_value)+); - $crate::sha256::HashEngine::from_midstate(MIDSTATE) - } - } - } -} - /// Macro used to define a newtype tagged hash. /// /// This macro creates two types: