From 25c4c78e2629f0ecb9d451845ff1cf6d8e12e04d Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 29 Oct 2024 13:58:50 +1100 Subject: [PATCH 1/5] hashes: Put attribute under rustdoc Like we do for all the other macros ptu the `macro_export` attribute below the macro comments. --- hashes/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index 942b8a788..480d336ca 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -2,8 +2,8 @@ //! Public macros. -#[macro_export] /// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`. +#[macro_export] macro_rules! hex_fmt_impl( ($reverse:expr, $len:expr, $ty:ident) => ( $crate::hex_fmt_impl!($reverse, $len, $ty, ); From e4486d07f00d15718fef8fff30bdeab99393043a Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 29 Oct 2024 14:01:50 +1100 Subject: [PATCH 2/5] hashes: Hide macros from docs These three macros are solely provided to reduce code duplication, they are only part of the public API because they are used by the "real" public macro `hash_newtype`. --- hashes/src/macros.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index 480d336ca..2b5113818 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -3,6 +3,7 @@ //! Public macros. /// 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) => ( @@ -48,6 +49,7 @@ macro_rules! hex_fmt_impl( ); /// Adds slicing traits implementations to a given type `$ty` +#[doc(hidden)] #[macro_export] macro_rules! borrow_slice_impl( ($ty:ident) => ( @@ -439,6 +441,7 @@ pub mod serde_details { /// Implements `Serialize` and `Deserialize` for a type `$t` which /// represents a newtype over a byte-slice over length `$len`. +#[doc(hidden)] #[macro_export] #[cfg(feature = "serde")] macro_rules! serde_impl( From baab5e580d33dfe5143e80c3efa1aa628d3dc084 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 29 Oct 2024 14:04:52 +1100 Subject: [PATCH 3/5] hashes: Move private macro We have two files one for public macros and one for private macros. Move the `engine_input_impl` macro to the private macros file. Requires change to call sites because we do not have `use_macros` attribute on the `internal_macros` file. --- hashes/src/internal_macros.rs | 31 +++++++++++++++++++++++++++++++ hashes/src/macros.rs | 30 ------------------------------ hashes/src/ripemd160.rs | 2 +- hashes/src/sha1.rs | 2 +- hashes/src/sha256.rs | 2 +- hashes/src/sha512.rs | 2 +- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/hashes/src/internal_macros.rs b/hashes/src/internal_macros.rs index aea52dfd0..c17c8f1a8 100644 --- a/hashes/src/internal_macros.rs +++ b/hashes/src/internal_macros.rs @@ -253,3 +253,34 @@ macro_rules! impl_io_write { } } pub(crate) use impl_io_write; + +macro_rules! engine_input_impl( + () => ( + #[cfg(not(hashes_fuzz))] + fn input(&mut self, mut inp: &[u8]) { + + while !inp.is_empty() { + let buf_idx = $crate::incomplete_block_len(self); + let rem_len = ::BLOCK_SIZE - buf_idx; + let write_len = cmp::min(rem_len, inp.len()); + + self.buffer[buf_idx..buf_idx + write_len] + .copy_from_slice(&inp[..write_len]); + self.bytes_hashed += write_len as u64; + if $crate::incomplete_block_len(self) == 0 { + self.process_block(); + } + inp = &inp[write_len..]; + } + } + + #[cfg(hashes_fuzz)] + fn input(&mut self, inp: &[u8]) { + for c in inp { + self.buffer[0] ^= *c; + } + self.bytes_hashed += inp.len() as u64; + } + ) +); +pub(crate) use engine_input_impl; diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index 2b5113818..45b7e9f5a 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -70,36 +70,6 @@ macro_rules! borrow_slice_impl( ) ); -macro_rules! engine_input_impl( - () => ( - #[cfg(not(hashes_fuzz))] - fn input(&mut self, mut inp: &[u8]) { - - while !inp.is_empty() { - let buf_idx = $crate::incomplete_block_len(self); - let rem_len = ::BLOCK_SIZE - buf_idx; - let write_len = cmp::min(rem_len, inp.len()); - - self.buffer[buf_idx..buf_idx + write_len] - .copy_from_slice(&inp[..write_len]); - self.bytes_hashed += write_len as u64; - if $crate::incomplete_block_len(self) == 0 { - self.process_block(); - } - inp = &inp[write_len..]; - } - } - - #[cfg(hashes_fuzz)] - fn input(&mut self, inp: &[u8]) { - for c in inp { - self.buffer[0] ^= *c; - } - self.bytes_hashed += inp.len() as u64; - } - ) -); - /// Creates a new newtype around a [`Hash`] type. /// /// The syntax is similar to the usual tuple struct syntax: diff --git a/hashes/src/ripemd160.rs b/hashes/src/ripemd160.rs index d77a2d928..3732cfb0b 100644 --- a/hashes/src/ripemd160.rs +++ b/hashes/src/ripemd160.rs @@ -85,7 +85,7 @@ impl crate::HashEngine for HashEngine { fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed } - engine_input_impl!(); + crate::internal_macros::engine_input_impl!(); } #[cfg(feature = "small-hash")] diff --git a/hashes/src/sha1.rs b/hashes/src/sha1.rs index b028dd75a..134a6178a 100644 --- a/hashes/src/sha1.rs +++ b/hashes/src/sha1.rs @@ -77,7 +77,7 @@ impl crate::HashEngine for HashEngine { fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed } - engine_input_impl!(); + crate::internal_macros::engine_input_impl!(); } impl HashEngine { diff --git a/hashes/src/sha256.rs b/hashes/src/sha256.rs index 5b85bac4b..7bd2576db 100644 --- a/hashes/src/sha256.rs +++ b/hashes/src/sha256.rs @@ -132,7 +132,7 @@ impl crate::HashEngine for HashEngine { fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed } - engine_input_impl!(); + crate::internal_macros::engine_input_impl!(); } impl Hash { diff --git a/hashes/src/sha512.rs b/hashes/src/sha512.rs index 0b3168133..793687abf 100644 --- a/hashes/src/sha512.rs +++ b/hashes/src/sha512.rs @@ -118,7 +118,7 @@ impl crate::HashEngine for HashEngine { fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed } - engine_input_impl!(); + crate::internal_macros::engine_input_impl!(); } #[allow(non_snake_case)] From 2868985a915b7cd2c2df370b534b98ead7d0b64b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 29 Oct 2024 14:09:18 +1100 Subject: [PATCH 4/5] Replace TBD with next hashes release version We are about to release `bitcoin_hashes 0.15.0`, replace the TBD string with the version number. Requires changing `allow(deprecated_in_future)` attribute to `allow(deprecated)` (in functions that are them self deprecated). --- hashes/src/hmac.rs | 2 +- hashes/src/internal_macros.rs | 2 +- hashes/src/lib.rs | 4 ++-- hashes/src/macros.rs | 6 +++--- hashes/src/sha256.rs | 2 +- hashes/src/sha256t.rs | 6 ++++-- hashes/src/siphash24.rs | 3 ++- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/hashes/src/hmac.rs b/hashes/src/hmac.rs index 2e30277f7..b3f931a12 100644 --- a/hashes/src/hmac.rs +++ b/hashes/src/hmac.rs @@ -129,7 +129,7 @@ impl Hash for Hmac { fn from_byte_array(bytes: T::Bytes) -> Self { Hmac(T::from_byte_array(bytes)) } - #[allow(deprecated_in_future)] + #[allow(deprecated)] fn from_slice(sl: &[u8]) -> Result, FromSliceError> { T::from_slice(sl).map(Hmac) } fn to_byte_array(self) -> Self::Bytes { self.0.to_byte_array() } diff --git a/hashes/src/internal_macros.rs b/hashes/src/internal_macros.rs index c17c8f1a8..929399342 100644 --- a/hashes/src/internal_macros.rs +++ b/hashes/src/internal_macros.rs @@ -99,7 +99,7 @@ macro_rules! hash_trait_impls { fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) } - #[allow(deprecated_in_future)] + #[allow(deprecated)] fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result, $crate::FromSliceError> { Self::from_slice(sl) } diff --git a/hashes/src/lib.rs b/hashes/src/lib.rs index 54302534b..71ee874b3 100644 --- a/hashes/src/lib.rs +++ b/hashes/src/lib.rs @@ -112,7 +112,7 @@ pub mod sha512; pub mod sha512_256; pub mod siphash24; -#[deprecated(since = "TBD", note = "use crate::macros instead")] +#[deprecated(since = "0.15.0", note = "use crate::macros instead")] pub mod serde_macros { //! Macros for serde trait implementations, and supporting code. @@ -284,7 +284,7 @@ pub trait Hash: fn from_byte_array(bytes: Self::Bytes) -> Self; /// Copies a byte slice into a hash object. - #[deprecated(since = "TBD", note = "use `from_byte_array` instead")] + #[deprecated(since = "0.15.0", note = "use `from_byte_array` instead")] fn from_slice(sl: &[u8]) -> Result; /// Returns the underlying byte array. diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index 45b7e9f5a..46bffc5fd 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -175,8 +175,8 @@ macro_rules! hash_newtype { } /// Copies a byte slice into a hash object. - #[deprecated(since = "TBD", note = "use `from_byte_array` instead")] - #[allow(deprecated_in_future)] + #[deprecated(since = "0.15.0", note = "use `from_byte_array` instead")] + #[allow(deprecated)] pub fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<$newtype, $crate::FromSliceError> { Ok($newtype(<$hash as $crate::Hash>::from_slice(sl)?)) } @@ -213,7 +213,7 @@ macro_rules! hash_newtype { fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) } #[inline] - #[allow(deprecated_in_future)] + #[allow(deprecated)] fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<$newtype, $crate::FromSliceError> { Self::from_slice(sl) } diff --git a/hashes/src/sha256.rs b/hashes/src/sha256.rs index 7bd2576db..4aa2c6467 100644 --- a/hashes/src/sha256.rs +++ b/hashes/src/sha256.rs @@ -144,7 +144,7 @@ impl Hash { /// Computes hash from `bytes` in `const` context. /// /// Warning: this function is inefficient. It should be only used in `const` context. - #[deprecated(since = "TBD", note = "use `Self::hash_unoptimized` instead")] + #[deprecated(since = "0.15.0", note = "use `Self::hash_unoptimized` instead")] pub const fn const_hash(bytes: &[u8]) -> Self { Hash::hash_unoptimized(bytes) } /// Computes hash from `bytes` in `const` context. diff --git a/hashes/src/sha256t.rs b/hashes/src/sha256t.rs index af249b0fd..f68991780 100644 --- a/hashes/src/sha256t.rs +++ b/hashes/src/sha256t.rs @@ -43,7 +43,7 @@ where } /// Copies a byte slice into a hash object. - #[deprecated(since = "TBD", note = "use `from_byte_array` instead")] + #[deprecated(since = "0.15.0", note = "use `from_byte_array` instead")] pub fn from_slice(sl: &[u8]) -> Result, FromSliceError> { if sl.len() != 32 { Err(FromSliceError { expected: 32, got: sl.len() }) @@ -186,6 +186,7 @@ macro_rules! sha256t_tag { /// The syntax is: /// /// ``` +/// # #[allow(deprecated)] { /// # use bitcoin_hashes::sha256t_hash_newtype; /// sha256t_hash_newtype! { /// /// Optional documentation details here. @@ -197,6 +198,7 @@ macro_rules! sha256t_tag { /// #[hash_newtype(backward)] /// pub struct FooHash(_); /// } +/// # } /// ``` /// /// The structs must be defined in this order - tag first, then hash type. `hash_str` marker @@ -211,7 +213,7 @@ macro_rules! sha256t_tag { /// /// [`hash_newtype`]: crate::hash_newtype #[macro_export] -#[deprecated(since = "TBD", note = "use `sha256_tag!` combined with `hash_newtype!` instead")] +#[deprecated(since = "0.15.0", note = "use `sha256_tag!` combined with `hash_newtype!` instead")] macro_rules! sha256t_hash_newtype { ($(#[$($tag_attr:tt)*])* $tag_vis:vis struct $tag:ident = $constructor:tt($($tag_value:tt)+); $(#[$($hash_attr:tt)*])* $hash_vis:vis struct $hash_name:ident($(#[$($field_attr:tt)*])* _);) => { $crate::sha256t_tag_struct!($tag_vis, $tag, stringify!($hash_name), $(#[$($tag_attr)*])*); diff --git a/hashes/src/siphash24.rs b/hashes/src/siphash24.rs index a40f8185c..c9ebda442 100644 --- a/hashes/src/siphash24.rs +++ b/hashes/src/siphash24.rs @@ -1,3 +1,4 @@ + // SPDX-License-Identifier: CC0-1.0 //! SipHash 2-4 implementation. @@ -203,7 +204,7 @@ impl Hash { } /// Returns the (little endian) 64-bit integer representation of the hash value. - #[deprecated(since = "TBD", note = "use `to_u64` instead")] + #[deprecated(since = "0.15.0", note = "use `to_u64` instead")] pub fn as_u64(&self) -> u64 { self.to_u64() } /// Returns the (little endian) 64-bit integer representation of the hash value. From abcac540782dd84992e47f342929efd407746c65 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 29 Oct 2024 14:18:24 +1100 Subject: [PATCH 5/5] hashes: Move public macros Put the two "real" public macros at the top of the `macros` file and add a module level doc to link to them because they don't show up otherwise. --- hashes/src/macros.rs | 164 ++++++++++++++++++++++++++---------------- hashes/src/sha256t.rs | 35 --------- 2 files changed, 101 insertions(+), 98 deletions(-) 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: