bitcoin_private/
macros.rs

1//! Various macros used by the Rust Bitcoin ecosystem.
2//!
3
4/// Implements standard array methods for a given wrapper type.
5#[macro_export]
6macro_rules! impl_array_newtype {
7    ($thing:ident, $ty:ty, $len:literal) => {
8        impl $thing {
9            /// Converts the object to a raw pointer.
10            #[inline]
11            pub fn as_ptr(&self) -> *const $ty {
12                let &$thing(ref dat) = self;
13                dat.as_ptr()
14            }
15
16            /// Converts the object to a mutable raw pointer.
17            #[inline]
18            pub fn as_mut_ptr(&mut self) -> *mut $ty {
19                let &mut $thing(ref mut dat) = self;
20                dat.as_mut_ptr()
21            }
22
23            /// Returns the length of the object as an array.
24            #[inline]
25            pub fn len(&self) -> usize { $len }
26
27            /// Returns whether the object, as an array, is empty. Always false.
28            #[inline]
29            pub fn is_empty(&self) -> bool { false }
30        }
31
32        impl<'a> core::convert::From<[$ty; $len]> for $thing {
33            fn from(data: [$ty; $len]) -> Self { $thing(data) }
34        }
35
36        impl<'a> core::convert::From<&'a [$ty; $len]> for $thing {
37            fn from(data: &'a [$ty; $len]) -> Self { $thing(*data) }
38        }
39
40        impl<'a> core::convert::TryFrom<&'a [$ty]> for $thing {
41            type Error = core::array::TryFromSliceError;
42
43            fn try_from(data: &'a [$ty]) -> Result<Self, Self::Error> {
44                use core::convert::TryInto;
45
46                Ok($thing(data.try_into()?))
47            }
48        }
49
50        impl AsRef<[$ty; $len]> for $thing {
51            fn as_ref(&self) -> &[$ty; $len] { &self.0 }
52        }
53
54        impl AsMut<[$ty; $len]> for $thing {
55            fn as_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
56        }
57
58        impl AsRef<[$ty]> for $thing {
59            fn as_ref(&self) -> &[$ty] { &self.0 }
60        }
61
62        impl AsMut<[$ty]> for $thing {
63            fn as_mut(&mut self) -> &mut [$ty] { &mut self.0 }
64        }
65
66        impl core::borrow::Borrow<[$ty; $len]> for $thing {
67            fn borrow(&self) -> &[$ty; $len] { &self.0 }
68        }
69
70        impl core::borrow::BorrowMut<[$ty; $len]> for $thing {
71            fn borrow_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
72        }
73
74        // The following two are valid because `[T; N]: Borrow<[T]>`
75        impl core::borrow::Borrow<[$ty]> for $thing {
76            fn borrow(&self) -> &[$ty] { &self.0 }
77        }
78
79        impl core::borrow::BorrowMut<[$ty]> for $thing {
80            fn borrow_mut(&mut self) -> &mut [$ty] { &mut self.0 }
81        }
82
83        impl<I> core::ops::Index<I> for $thing
84        where
85            [$ty]: core::ops::Index<I>,
86        {
87            type Output = <[$ty] as core::ops::Index<I>>::Output;
88
89            #[inline]
90            fn index(&self, index: I) -> &Self::Output { &self.0[index] }
91        }
92    };
93}
94
95/// Implements `Debug` by calling through to `Display`.
96#[macro_export]
97macro_rules! debug_from_display {
98    ($thing:ident) => {
99        impl core::fmt::Debug for $thing {
100            fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
101                core::fmt::Display::fmt(self, f)
102            }
103        }
104    };
105}
106
107/// Asserts a boolean expression at compile time.
108#[macro_export]
109macro_rules! const_assert {
110    ($x:expr) => {{
111        const _: [(); 0 - !$x as usize] = [];
112    }};
113}