bitcoin_internals/
macros.rs1#[macro_export]
7macro_rules! const_assert {
8 ($x:expr $(; $message:expr)?) => {
9 const _: () = {
10 if !$x {
11 panic!(concat!("assertion ", stringify!($x), " failed" $(, ": ", $message)?))
13 }
14 };
15 }
16}
17
18#[macro_export]
22macro_rules! impl_to_hex_from_lower_hex {
23 ($t:ident, $hex_len_fn:expr) => {
24 impl $t {
25 pub fn to_hex(&self) -> alloc::string::String {
27 use core::fmt::Write;
28
29 let mut hex_string = alloc::string::String::with_capacity($hex_len_fn(self));
30 write!(&mut hex_string, "{:x}", self).expect("writing to string shouldn't fail");
31
32 hex_string
33 }
34 }
35 };
36}
37
38#[macro_export]
57macro_rules! transparent_newtype {
58 (
59 $(#[$($struct_attr:tt)*])*
60 $vis:vis struct $newtype:tt$(<$gen:ident $(= $default:ty)?>)?($($fields:tt)+) $(where $($where_ty:ty: $bound:path),* $(,)?)?;
61
62 impl$(<$gen2:tt>)? $newtype2:ident$(<$gen3:tt>)? {
63 $(
64 $(#[$($fn_attr:tt)*])*
65 $fn_vis:vis $(const)? fn $fn:ident($fn_arg_name:ident: $($fn_arg_ty:tt)+) -> $fn_ret_ty:ty;
66 )*
67 }
68 ) => {
69 $crate::_check_tts_eq!($newtype2, $newtype, "the type name in the impl block doesn't match the struct name");
70 $(
71 $crate::_check_tts_eq!($gen2, $gen, "the name of the left generic parameter in impl block doesn't match the one on struct");
76 $crate::_check_tts_eq!($gen3, $gen, "the name of the right generic parameter in impl block doesn't match the one on struct");
77 )?
78 $(#[$($struct_attr)*])*
79 #[repr(transparent)]
80 $vis struct $newtype$(<$gen $(= $default)?>)?($($fields)+) $(where $($where_ty: $bound),*)?;
81
82 impl$(<$gen2>)? $newtype$(<$gen3>)? $(where $($where_ty: $bound),*)? {
83 $crate::_transparent_ref_conversions! {
84 $crate::_transparent_newtype_inner_type!($($fields)+);
85 $(
86 $(#[$($fn_attr)*])*
87 $fn_vis fn $fn($fn_arg_name: $($fn_arg_ty)+) -> $fn_ret_ty;
88 )+
89 }
90 }
91 };
92}
93
94#[doc(hidden)]
95#[macro_export]
96macro_rules! _transparent_ref_conversions {
97 (
98 $inner:ty;
99 $(
100 $(#[$($fn_attr:tt)*])*
101 $fn_vis:vis $(const)? fn $fn:ident($fn_arg_name:ident: $($fn_arg_ty:tt)+) -> $fn_ret_ty:ty;
102 )+
103 ) => {
104 $(
105 $crate::_transparent_ref_conversion! {
106 $inner;
107 $(#[$($fn_attr)*])*
108 $fn_vis fn $fn($fn_arg_name: $($fn_arg_ty)+) -> $fn_ret_ty;
109 }
110 )+
111 }
112}
113
114#[doc(hidden)]
115#[macro_export]
116macro_rules! _transparent_ref_conversion {
117 (
118 $inner:ty;
119 $(#[$($from_ref_attr:tt)*])*
120 $from_ref_vis:vis fn $from_ref:ident($from_ref_arg_name:ident: &_) -> $fn_ret_ty:ty;
121 ) => {
122 #[inline]
123 $(#[$($from_ref_attr)*])*
124 $from_ref_vis const fn $from_ref($from_ref_arg_name: &$inner) -> &Self {
125 unsafe { &*($from_ref_arg_name as *const $inner as *const Self) }
130 }
131 };
132 (
133 $inner:ty;
134 $(#[$($from_mut_attr:tt)*])*
135 $from_mut_vis:vis fn $from_mut:ident($from_mut_arg_name:ident: &mut _) -> $fn_ret_ty:ty;
136 ) => {
137 #[inline]
138 $(#[$($from_mut_attr)*])*
139 $from_mut_vis fn $from_mut($from_mut_arg_name: &mut $inner) -> &mut Self {
140 unsafe { &mut *($from_mut_arg_name as *mut $inner as *mut Self) }
145 }
146 };
147 (
148 $inner:ty;
149 $(#[$($from_box_attr:tt)*])*
150 $from_box_vis:vis fn $from_box:ident($from_box_arg_name:ident: Box<_>) -> $fn_ret_ty:ty;
151 ) => {
152 $crate::_emit_alloc! {
153 $(#[$($from_box_attr)*])*
154 #[inline]
155 $from_box_vis fn $from_box($from_box_arg_name: $crate::_export::alloc::boxed::Box<$inner>) -> $crate::_export::alloc::boxed::Box<Self> {
156 let ptr = $crate::_export::alloc::boxed::Box::into_raw($from_box_arg_name);
157 unsafe { $crate::_export::alloc::boxed::Box::from_raw(ptr as *mut Self) }
161 }
162 }
163 };
164
165 (
166 $inner:ty;
167 $(#[$($from_rc_attr:tt)*])*
168 $from_rc_vis:vis fn $from_rc:ident($from_rc_arg_name:ident: Rc<_>) -> $fn_ret_ty:ty;
169 ) => {
170 $crate::_emit_alloc! {
171 $(#[$($from_rc_attr)*])*
172 #[inline]
173 $from_rc_vis fn $from_rc($from_rc_arg_name: $crate::_export::alloc::rc::Rc<$inner>) -> $crate::_export::alloc::rc::Rc<Self> {
174 let ptr = $crate::_export::alloc::rc::Rc::into_raw($from_rc_arg_name);
175 unsafe { $crate::_export::alloc::rc::Rc::from_raw(ptr as *mut Self) }
179 }
180 }
181 };
182
183 (
184 $inner:ty;
185 $(#[$($from_arc_attr:tt)*])*
186 $from_arc_vis:vis fn $from_arc:ident($from_arc_arg_name:ident: Arc<_>) -> $fn_ret_ty:ty;
187 ) => {
188 $crate::_emit_alloc! {
189 $(#[$($from_arc_attr)*])*
190 #[cfg(target_has_atomic = "ptr")]
191 #[inline]
192 $from_arc_vis fn $from_arc($from_arc_arg_name: $crate::_export::alloc::sync::Arc<$inner>) -> $crate::_export::alloc::sync::Arc<Self> {
193 let ptr = $crate::_export::alloc::sync::Arc::into_raw($from_arc_arg_name);
194 unsafe { $crate::_export::alloc::sync::Arc::from_raw(ptr as *mut Self) }
198 }
199 }
200 }
201}
202
203#[doc(hidden)]
204#[macro_export]
205macro_rules! _check_tts_eq {
206 ($left:tt, $right:tt, $message:literal) => {
207 macro_rules! token_eq {
208 ($right) => {};
209 ($any:tt) => {
210 compile_error!($message)
211 };
212 }
213 token_eq!($left);
214 };
215}
216
217#[doc(hidden)]
218#[macro_export]
219macro_rules! _transparent_newtype_inner_type {
220 ($(#[$($field_attr:tt)*])* $inner:ty) => {
221 $inner
222 };
223 ($(#[$($phantom_attr:tt)*])* PhantomData<$phantom:ty>, $(#[$($field_attr:tt)*])* $inner:ty) => {
224 $inner
225 };
226}
227
228#[cfg(feature = "alloc")]
232#[doc(hidden)]
233#[macro_export]
234macro_rules! _emit_alloc {
235 ($($tokens:tt)*) => { $($tokens)* };
236}
237
238#[cfg(not(feature = "alloc"))]
242#[doc(hidden)]
243#[macro_export]
244macro_rules! _emit_alloc {
245 ($($tokens:tt)*) => {};
246}
247
248#[macro_export]
250macro_rules! impl_array_newtype {
251 ($thing:ident, $ty:ty, $len:literal) => {
252 impl $thing {
253 #[inline]
255 pub fn from_byte_array(bytes: [u8; $len]) -> Self { Self(bytes) }
256
257 #[inline]
259 pub fn as_byte_array(&self) -> &[u8; $len] { &self.0 }
260
261 #[inline]
263 pub fn to_byte_array(self) -> [u8; $len] {
264 fn check_copy<T: Copy>() {}
267 check_copy::<$thing>();
268
269 self.0
270 }
271
272 #[inline]
274 pub fn to_vec(self) -> alloc::vec::Vec<u8> { self.0.to_vec() }
275
276 #[inline]
278 pub fn as_bytes(&self) -> &[u8] { &self.0 }
279
280 #[inline]
282 pub fn as_ptr(&self) -> *const $ty {
283 let &$thing(ref dat) = self;
284 dat.as_ptr()
285 }
286
287 #[inline]
289 pub fn as_mut_ptr(&mut self) -> *mut $ty {
290 let &mut $thing(ref mut dat) = self;
291 dat.as_mut_ptr()
292 }
293
294 #[inline]
296 pub fn len(&self) -> usize { $len }
297
298 #[inline]
300 pub fn is_empty(&self) -> bool { false }
301 }
302
303 impl<'a> core::convert::From<[$ty; $len]> for $thing {
304 fn from(data: [$ty; $len]) -> Self { $thing(data) }
305 }
306
307 impl<'a> core::convert::From<&'a [$ty; $len]> for $thing {
308 fn from(data: &'a [$ty; $len]) -> Self { $thing(*data) }
309 }
310
311 impl<'a> core::convert::TryFrom<&'a [$ty]> for $thing {
312 type Error = core::array::TryFromSliceError;
313
314 fn try_from(data: &'a [$ty]) -> core::result::Result<Self, Self::Error> {
315 use core::convert::TryInto;
316
317 Ok($thing(data.try_into()?))
318 }
319 }
320
321 impl AsRef<[$ty; $len]> for $thing {
322 fn as_ref(&self) -> &[$ty; $len] { &self.0 }
323 }
324
325 impl AsMut<[$ty; $len]> for $thing {
326 fn as_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
327 }
328
329 impl AsRef<[$ty]> for $thing {
330 fn as_ref(&self) -> &[$ty] { &self.0 }
331 }
332
333 impl AsMut<[$ty]> for $thing {
334 fn as_mut(&mut self) -> &mut [$ty] { &mut self.0 }
335 }
336
337 impl core::borrow::Borrow<[$ty; $len]> for $thing {
338 fn borrow(&self) -> &[$ty; $len] { &self.0 }
339 }
340
341 impl core::borrow::BorrowMut<[$ty; $len]> for $thing {
342 fn borrow_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
343 }
344
345 impl core::borrow::Borrow<[$ty]> for $thing {
347 fn borrow(&self) -> &[$ty] { &self.0 }
348 }
349
350 impl core::borrow::BorrowMut<[$ty]> for $thing {
351 fn borrow_mut(&mut self) -> &mut [$ty] { &mut self.0 }
352 }
353
354 impl<I> core::ops::Index<I> for $thing
355 where
356 [$ty]: core::ops::Index<I>,
357 {
358 type Output = <[$ty] as core::ops::Index<I>>::Output;
359
360 #[inline]
361 fn index(&self, index: I) -> &Self::Output { &self.0[index] }
362 }
363 };
364}