bitcoin_hashes/
internal_macros.rs1macro_rules! arr_newtype_fmt_impl {
6 ($ty:ident, $bytes:expr $(, $gen:ident: $gent:ident)*) => {
7 impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> {
8 #[inline]
9 fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
10 #[allow(unused)]
11 use crate::Hash as _;
12 let case = $crate::hex::Case::Lower;
13 if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
14 $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
15 } else {
16 $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
17 }
18 }
19 }
20
21 impl<$($gen: $gent),*> $crate::_export::_core::fmt::UpperHex for $ty<$($gen),*> {
22 #[inline]
23 fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
24 #[allow(unused)]
25 use crate::Hash as _;
26 let case = $crate::hex::Case::Upper;
27 if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
28 $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
29 } else {
30 $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
31 }
32 }
33 }
34
35 impl<$($gen: $gent),*> $crate::_export::_core::fmt::Display for $ty<$($gen),*> {
36 #[inline]
37 fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
38 $crate::_export::_core::fmt::LowerHex::fmt(self, f)
39 }
40 }
41
42 impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> {
43 #[inline]
44 fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
45 write!(f, "{:#}", self)
46 }
47 }
48 }
49}
50pub(crate) use arr_newtype_fmt_impl;
51
52macro_rules! hash_trait_impls {
72 ($bits:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
73 impl<$($gen: $gent),*> Hash<$($gen),*> {
74 pub fn forward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
79 $crate::hex::DisplayHex::as_hex(&self.0)
80 }
81
82 pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
87 $crate::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev())
88 }
89
90 pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self {
93 unsafe { &*(bytes as *const _ as *const Self) }
95 }
96
97 pub fn from_bytes_mut(bytes: &mut [u8; $bits / 8]) -> &mut Self {
100 unsafe { &mut *(bytes as *mut _ as *mut Self) }
102 }
103 }
104
105 impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> {
106 type Err = $crate::hex::HexToArrayError;
107 fn from_str(s: &str) -> Result<Self, Self::Err> {
108 use $crate::hex::{FromHex, HexToBytesIter};
109 use $crate::Hash;
110
111 let inner: [u8; $bits / 8] = if $reverse {
112 FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
113 } else {
114 FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
115 };
116 Ok(Self::from_byte_array(inner))
117 }
118 }
119
120 $crate::internal_macros::arr_newtype_fmt_impl!(Hash, $bits / 8 $(, $gen: $gent)*);
121 serde_impl!(Hash, $bits / 8 $(, $gen: $gent)*);
122 borrow_slice_impl!(Hash $(, $gen: $gent)*);
123
124 impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8; $bits / 8]> for Hash<$($gen),*> {
125 fn as_ref(&self) -> &[u8; $bits / 8] {
126 &self.0
127 }
128 }
129
130 impl<I: SliceIndex<[u8]> $(, $gen: $gent)*> Index<I> for Hash<$($gen),*> {
131 type Output = I::Output;
132
133 #[inline]
134 fn index(&self, index: I) -> &Self::Output {
135 &self.0[index]
136 }
137 }
138
139 impl<$($gen: $gent),*> crate::Hash for Hash<$($gen),*> {
140 type Engine = HashEngine;
141 type Bytes = [u8; $bits / 8];
142
143 const LEN: usize = $bits / 8;
144 const DISPLAY_BACKWARD: bool = $reverse;
145
146 fn engine() -> Self::Engine {
147 Self::internal_engine()
148 }
149
150 fn from_engine(e: HashEngine) -> Hash<$($gen),*> {
151 from_engine(e)
152 }
153
154 fn from_slice(sl: &[u8]) -> Result<Hash<$($gen),*>, FromSliceError> {
155 if sl.len() != $bits / 8 {
156 Err(FromSliceError{expected: Self::LEN, got: sl.len()})
157 } else {
158 let mut ret = [0; $bits / 8];
159 ret.copy_from_slice(sl);
160 Ok(Self::internal_new(ret))
161 }
162 }
163
164 fn to_byte_array(self) -> Self::Bytes {
165 self.0
166 }
167
168 fn as_byte_array(&self) -> &Self::Bytes {
169 &self.0
170 }
171
172 fn from_byte_array(bytes: Self::Bytes) -> Self {
173 Self::internal_new(bytes)
174 }
175
176 fn all_zeros() -> Self {
177 Hash::internal_new([0x00; $bits / 8])
178 }
179 }
180 }
181}
182pub(crate) use hash_trait_impls;
183
184macro_rules! hash_type {
199 ($bits:expr, $reverse:expr, $doc:literal, $schemars:literal) => {
200 #[doc = $doc]
201 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
202 #[cfg_attr(feature = "schemars", derive(crate::schemars::JsonSchema))]
203 #[repr(transparent)]
204 pub struct Hash(
205 #[cfg_attr(feature = "schemars", schemars(schema_with = $schemars))] [u8; $bits / 8],
206 );
207
208 impl Hash {
209 fn internal_new(arr: [u8; $bits / 8]) -> Self { Hash(arr) }
210
211 fn internal_engine() -> HashEngine { Default::default() }
212 }
213
214 crate::internal_macros::hash_trait_impls!($bits, $reverse);
215 };
216}
217pub(crate) use hash_type;