alloy_primitives/bits/
macros.rs

1/// Wrap a fixed-size byte array in a newtype, delegating all methods to the
2/// underlying [`crate::FixedBytes`].
3///
4/// This functionally creates a new named `FixedBytes` that cannot be
5/// type-confused for another named `FixedBytes`.
6///
7/// **NOTE:** This macro currently requires:
8/// - `#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]` at the top level of the crate.
9/// - The `derive_more` crate in scope.
10///
11/// # Examples
12///
13/// ```
14/// use alloy_primitives::wrap_fixed_bytes;
15///
16/// // These hashes are the same length, and have the same functionality, but
17/// // are distinct types
18/// wrap_fixed_bytes!(pub struct KeccakOutput<32>;);
19/// wrap_fixed_bytes!(pub struct MerkleTreeItem<32>;);
20/// ```
21#[macro_export]
22macro_rules! wrap_fixed_bytes {
23    (
24        $(#[$attrs:meta])*
25        $vis:vis struct $name:ident<$n:literal>;
26    ) => {
27        $crate::wrap_fixed_bytes!(
28            extra_derives: [$crate::private::derive_more::Display],
29            $(#[$attrs])*
30            $vis struct $name<$n>;
31        );
32    };
33
34    (
35        extra_derives: [$($extra_derives:path),* $(,)?],
36        $(#[$attrs:meta])*
37        $vis:vis struct $name:ident<$n:literal>;
38    ) => {
39        $(#[$attrs])*
40        #[derive(
41            Clone,
42            Copy,
43            Default,
44            PartialEq,
45            Eq,
46            PartialOrd,
47            Ord,
48            Hash,
49            $crate::private::derive_more::AsMut,
50            $crate::private::derive_more::AsRef,
51            $crate::private::derive_more::BitAnd,
52            $crate::private::derive_more::BitAndAssign,
53            $crate::private::derive_more::BitOr,
54            $crate::private::derive_more::BitOrAssign,
55            $crate::private::derive_more::BitXor,
56            $crate::private::derive_more::BitXorAssign,
57            $crate::private::derive_more::Not,
58            $crate::private::derive_more::Deref,
59            $crate::private::derive_more::DerefMut,
60            $crate::private::derive_more::From,
61            $crate::private::derive_more::FromStr,
62            $crate::private::derive_more::Index,
63            $crate::private::derive_more::IndexMut,
64            $crate::private::derive_more::Into,
65            $crate::private::derive_more::IntoIterator,
66            $crate::private::derive_more::LowerHex,
67            $crate::private::derive_more::UpperHex,
68            $(
69                $extra_derives,
70            )*
71        )]
72        #[repr(transparent)]
73        $vis struct $name(#[into_iterator(owned, ref, ref_mut)] pub $crate::FixedBytes<$n>);
74
75        impl $crate::private::From<[u8; $n]> for $name {
76            #[inline]
77            fn from(value: [u8; $n]) -> Self {
78                Self($crate::FixedBytes(value))
79            }
80        }
81
82        impl $crate::private::From<$name> for [u8; $n] {
83            #[inline]
84            fn from(value: $name) -> Self {
85                value.0 .0
86            }
87        }
88
89        impl<'a> $crate::private::From<&'a [u8; $n]> for $name {
90            #[inline]
91            fn from(value: &'a [u8; $n]) -> Self {
92                Self($crate::FixedBytes(*value))
93            }
94        }
95
96        impl<'a> $crate::private::From<&'a mut [u8; $n]> for $name {
97            #[inline]
98            fn from(value: &'a mut [u8; $n]) -> Self {
99                Self($crate::FixedBytes(*value))
100            }
101        }
102
103        impl $crate::private::TryFrom<&[u8]> for $name {
104            type Error = $crate::private::core::array::TryFromSliceError;
105
106            #[inline]
107            fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
108                <&Self as $crate::private::TryFrom<&[u8]>>::try_from(slice).copied()
109            }
110        }
111
112        impl $crate::private::TryFrom<&mut [u8]> for $name {
113            type Error = $crate::private::core::array::TryFromSliceError;
114
115            #[inline]
116            fn try_from(slice: &mut [u8]) -> Result<Self, Self::Error> {
117                <Self as $crate::private::TryFrom<&[u8]>>::try_from(&*slice)
118            }
119        }
120
121        impl<'a> $crate::private::TryFrom<&'a [u8]> for &'a $name {
122            type Error = $crate::private::core::array::TryFromSliceError;
123
124            #[inline]
125            #[allow(unsafe_code)]
126            fn try_from(slice: &'a [u8]) -> Result<&'a $name, Self::Error> {
127                // SAFETY: `$name` is `repr(transparent)` for `FixedBytes<$n>`
128                // and consequently `[u8; $n]`
129                <&[u8; $n] as $crate::private::TryFrom<&[u8]>>::try_from(slice)
130                    .map(|array_ref| unsafe { $crate::private::core::mem::transmute(array_ref) })
131            }
132        }
133
134        impl<'a> $crate::private::TryFrom<&'a mut [u8]> for &'a mut $name {
135            type Error = $crate::private::core::array::TryFromSliceError;
136
137            #[inline]
138            #[allow(unsafe_code)]
139            fn try_from(slice: &'a mut [u8]) -> Result<&'a mut $name, Self::Error> {
140                // SAFETY: `$name` is `repr(transparent)` for `FixedBytes<$n>`
141                // and consequently `[u8; $n]`
142                <&mut [u8; $n] as $crate::private::TryFrom<&mut [u8]>>::try_from(slice)
143                    .map(|array_ref| unsafe { $crate::private::core::mem::transmute(array_ref) })
144            }
145        }
146
147        impl $crate::private::AsRef<[u8; $n]> for $name {
148            #[inline]
149            fn as_ref(&self) -> &[u8; $n] {
150                &self.0 .0
151            }
152        }
153
154        impl $crate::private::AsMut<[u8; $n]> for $name {
155            #[inline]
156            fn as_mut(&mut self) -> &mut [u8; $n] {
157                &mut self.0 .0
158            }
159        }
160
161        impl $crate::private::AsRef<[u8]> for $name {
162            #[inline]
163            fn as_ref(&self) -> &[u8] {
164                &self.0 .0
165            }
166        }
167
168        impl $crate::private::AsMut<[u8]> for $name {
169            #[inline]
170            fn as_mut(&mut self) -> &mut [u8] {
171                &mut self.0 .0
172            }
173        }
174
175        impl $crate::private::core::fmt::Debug for $name {
176            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
177                $crate::private::core::fmt::Debug::fmt(&self.0, f)
178            }
179        }
180
181        impl $crate::private::core::ops::BitAnd<&Self> for $name {
182            type Output = Self;
183
184            #[inline]
185            fn bitand(self, rhs: &Self) -> Self {
186                Self(self.0.bitand(&rhs.0))
187            }
188        }
189
190        impl $crate::private::core::ops::BitAndAssign<&Self> for $name {
191            #[inline]
192            fn bitand_assign(&mut self, rhs: &Self) {
193                self.0.bitand_assign(&rhs.0)
194            }
195        }
196
197        impl $crate::private::core::ops::BitOr<&Self> for $name {
198            type Output = Self;
199
200            #[inline]
201            fn bitor(self, rhs: &Self) -> Self {
202                Self(self.0.bitor(&rhs.0))
203            }
204        }
205
206        impl $crate::private::core::ops::BitOrAssign<&Self> for $name {
207            #[inline]
208            fn bitor_assign(&mut self, rhs: &Self) {
209                self.0.bitor_assign(&rhs.0)
210            }
211        }
212
213        impl $crate::private::core::ops::BitXor<&Self> for $name {
214            type Output = Self;
215
216            #[inline]
217            fn bitxor(self, rhs: &Self) -> Self {
218                Self(self.0.bitxor(&rhs.0))
219            }
220        }
221
222        impl $crate::private::core::ops::BitXorAssign<&Self> for $name {
223            #[inline]
224            fn bitxor_assign(&mut self, rhs: &Self) {
225                self.0.bitxor_assign(&rhs.0)
226            }
227        }
228
229        $crate::impl_fb_traits!($name, $n);
230        $crate::impl_rlp!($name, $n);
231        $crate::impl_serde!($name);
232        $crate::impl_allocative!($name);
233        $crate::impl_arbitrary!($name, $n);
234        $crate::impl_rand!($name);
235        $crate::impl_diesel!($name, $n);
236
237        impl $name {
238            /// Array of Zero bytes.
239            pub const ZERO: Self = Self($crate::FixedBytes::ZERO);
240
241            /// Wraps the given byte array in this type.
242            #[inline]
243            pub const fn new(bytes: [u8; $n]) -> Self {
244                Self($crate::FixedBytes(bytes))
245            }
246
247            /// Creates a new byte array with the last byte set to `x`.
248            #[inline]
249            pub const fn with_last_byte(x: u8) -> Self {
250                Self($crate::FixedBytes::with_last_byte(x))
251            }
252
253            /// Creates a new byte array where all bytes are set to `byte`.
254            #[inline]
255            pub const fn repeat_byte(byte: u8) -> Self {
256                Self($crate::FixedBytes::repeat_byte(byte))
257            }
258
259            /// Returns the size of this array in bytes.
260            #[inline]
261            pub const fn len_bytes() -> usize {
262                $n
263            }
264
265            $crate::impl_getrandom!();
266            $crate::impl_rand!();
267
268            /// Create a new byte array from the given slice `src`.
269            ///
270            /// For a fallible version, use the `TryFrom<&[u8]>` implementation.
271            ///
272            /// # Note
273            ///
274            /// The given bytes are interpreted in big endian order.
275            ///
276            /// # Panics
277            ///
278            /// If the length of `src` and the number of bytes in `Self` do not match.
279            #[inline]
280            #[track_caller]
281            pub fn from_slice(src: &[u8]) -> Self {
282                match Self::try_from(src) {
283                    Ok(x) => x,
284                    Err(_) => panic!("cannot convert a slice of length {} to {}", src.len(), stringify!($name)),
285                }
286            }
287
288            /// Create a new byte array from the given slice `src`, left-padding it
289            /// with zeroes if necessary.
290            ///
291            /// # Note
292            ///
293            /// The given bytes are interpreted in big endian order.
294            ///
295            /// # Panics
296            ///
297            /// Panics if `src.len() > N`.
298            #[inline]
299            #[track_caller]
300            pub fn left_padding_from(value: &[u8]) -> Self {
301                Self($crate::FixedBytes::left_padding_from(value))
302            }
303
304            /// Create a new byte array from the given slice `src`, right-padding it
305            /// with zeroes if necessary.
306            ///
307            /// # Note
308            ///
309            /// The given bytes are interpreted in big endian order.
310            ///
311            /// # Panics
312            ///
313            /// Panics if `src.len() > N`.
314            #[inline]
315            #[track_caller]
316            pub fn right_padding_from(value: &[u8]) -> Self {
317                Self($crate::FixedBytes::right_padding_from(value))
318            }
319
320            /// Returns the inner bytes array.
321            #[inline]
322            pub const fn into_array(self) -> [u8; $n] {
323                self.0 .0
324            }
325
326            /// Returns `true` if all bits set in `b` are also set in `self`.
327            #[inline]
328            pub fn covers(&self, b: &Self) -> bool {
329                &(*b & *self) == b
330            }
331
332            /// Compile-time equality. NOT constant-time equality.
333            pub const fn const_eq(&self, other: &Self) -> bool {
334                self.0.const_eq(&other.0)
335            }
336
337            /// Computes the bitwise AND of two `FixedBytes`.
338            pub const fn bit_and(self, rhs: Self) -> Self {
339                Self(self.0.bit_and(rhs.0))
340            }
341
342            /// Computes the bitwise OR of two `FixedBytes`.
343            pub const fn bit_or(self, rhs: Self) -> Self {
344                Self(self.0.bit_or(rhs.0))
345            }
346
347            /// Computes the bitwise XOR of two `FixedBytes`.
348            pub const fn bit_xor(self, rhs: Self) -> Self {
349                Self(self.0.bit_xor(rhs.0))
350            }
351        }
352    };
353}
354
355// Extra traits that cannot be derived automatically
356#[doc(hidden)]
357#[macro_export]
358macro_rules! impl_fb_traits {
359    (impl<$($const:ident)?> Borrow<$t:ty> for $b:ty) => {
360        impl<$($const N: usize)?> $crate::private::Borrow<$t> for $b {
361            #[inline]
362            fn borrow(&self) -> &$t {
363                $crate::private::Borrow::borrow(&self.0)
364            }
365        }
366    };
367
368    (impl<$($const:ident)?> BorrowMut<$t:ty> for $b:ty) => {
369        impl<$($const N: usize)?> $crate::private::BorrowMut<$t> for $b {
370            #[inline]
371            fn borrow_mut(&mut self) -> &mut $t {
372                $crate::private::BorrowMut::borrow_mut(&mut self.0)
373            }
374        }
375    };
376
377    (unsafe impl<$lt:lifetime, $($const:ident)?> From<$a:ty> for $b:ty) => {
378        impl<$lt, $($const N: usize)?> $crate::private::From<$a> for $b {
379            #[inline]
380            #[allow(unsafe_code)]
381            fn from(value: $a) -> $b {
382                // SAFETY: guaranteed by caller
383                unsafe { $crate::private::core::mem::transmute::<$a, $b>(value) }
384            }
385        }
386    };
387
388    (impl<$($const:ident)?> cmp::$tr:ident<$a:ty> for $b:ty where fn $fn:ident -> $ret:ty $(, [$e:expr])?) => {
389        impl<$($const N: usize)?> $crate::private::$tr<$a> for $b {
390            #[inline]
391            fn $fn(&self, other: &$a) -> $ret {
392                $crate::private::$tr::$fn(&self.0 $([$e])?, other)
393            }
394        }
395
396        impl<$($const N: usize)?> $crate::private::$tr<$b> for $a {
397            #[inline]
398            fn $fn(&self, other: &$b) -> $ret {
399                $crate::private::$tr::$fn(self, &other.0 $([$e])?)
400            }
401        }
402
403        impl<$($const N: usize)?> $crate::private::$tr<&$a> for $b {
404            #[inline]
405            fn $fn(&self, other: &&$a) -> $ret {
406                $crate::private::$tr::$fn(&self.0 $([$e])?, *other)
407            }
408        }
409
410        impl<$($const N: usize)?> $crate::private::$tr<$b> for &$a {
411            #[inline]
412            fn $fn(&self, other: &$b) -> $ret {
413                $crate::private::$tr::$fn(*self, &other.0 $([$e])?)
414            }
415        }
416
417        impl<$($const N: usize)?> $crate::private::$tr<$a> for &$b {
418            #[inline]
419            fn $fn(&self, other: &$a) -> $ret {
420                $crate::private::$tr::$fn(&self.0 $([$e])?, other)
421            }
422        }
423
424        impl<$($const N: usize)?> $crate::private::$tr<&$b> for $a {
425            #[inline]
426            fn $fn(&self, other: &&$b) -> $ret {
427                $crate::private::$tr::$fn(self, &other.0 $([$e])?)
428            }
429        }
430    };
431
432    ($t:ty, $n:tt $(, $const:ident)?) => {
433        // Borrow is not automatically implemented for references
434        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for $t);
435        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for &$t);
436        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for &mut $t);
437        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for $t);
438        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for &$t);
439        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for &mut $t);
440
441        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8]>     for $t);
442        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8]>     for &mut $t);
443        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8; $n]> for $t);
444        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8; $n]> for &mut $t);
445
446        // Implement conversion traits for references with `mem::transmute`
447        // SAFETY: `repr(transparent)`
448        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a [u8; $n]>     for &'a $t);
449        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut [u8; $n]> for &'a $t);
450        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut [u8; $n]> for &'a mut $t);
451
452        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a $t>           for &'a [u8; $n]);
453        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut $t>       for &'a [u8; $n]);
454        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut $t>       for &'a mut [u8; $n]);
455
456        // Implement PartialEq, PartialOrd, with slice and array
457        $crate::impl_fb_traits!(impl<$($const)?> cmp::PartialEq<[u8]> for $t where fn eq -> bool);
458        $crate::impl_fb_traits!(impl<$($const)?> cmp::PartialEq<[u8; $n]> for $t where fn eq -> bool);
459        $crate::impl_fb_traits!(
460            impl<$($const)?> cmp::PartialOrd<[u8]> for $t
461            where
462                fn partial_cmp -> $crate::private::Option<$crate::private::Ordering>,
463                [..] // slices $t
464        );
465
466        impl<$($const N: usize)?> $crate::hex::FromHex for $t {
467            type Error = $crate::hex::FromHexError;
468
469            #[inline]
470            fn from_hex<T: $crate::private::AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
471                $crate::hex::decode_to_array(hex).map(Self::new)
472            }
473        }
474    };
475}
476
477#[doc(hidden)]
478#[macro_export]
479#[cfg(feature = "getrandom")]
480macro_rules! impl_getrandom {
481    () => {
482        /// Creates a new fixed byte array with the default cryptographic random number
483        /// generator.
484        ///
485        /// This is `rand::thread_rng` if the "rand" and "std" features are enabled, otherwise
486        /// it uses `getrandom::getrandom`. Both are cryptographically secure.
487        #[inline]
488        #[track_caller]
489        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
490        pub fn random() -> Self {
491            Self($crate::FixedBytes::random())
492        }
493
494        /// Tries to create a new fixed byte array with the default cryptographic random number
495        /// generator.
496        ///
497        /// See [`random`](Self::random) for more details.
498        #[inline]
499        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
500        pub fn try_random() -> $crate::private::Result<Self, $crate::private::getrandom::Error> {
501            $crate::FixedBytes::try_random().map(Self)
502        }
503
504        /// Fills this fixed byte array with the default cryptographic random number generator.
505        ///
506        /// See [`random`](Self::random) for more details.
507        #[inline]
508        #[track_caller]
509        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
510        pub fn randomize(&mut self) {
511            self.0.randomize();
512        }
513
514        /// Tries to fill this fixed byte array with the default cryptographic random number
515        /// generator.
516        ///
517        /// See [`random`](Self::random) for more details.
518        #[inline]
519        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
520        pub fn try_randomize(
521            &mut self,
522        ) -> $crate::private::Result<(), $crate::private::getrandom::Error> {
523            self.0.try_randomize()
524        }
525    };
526}
527
528#[doc(hidden)]
529#[macro_export]
530#[cfg(not(feature = "getrandom"))]
531macro_rules! impl_getrandom {
532    () => {};
533}
534
535#[doc(hidden)]
536#[macro_export]
537#[cfg(feature = "rand")]
538macro_rules! impl_rand {
539    () => {
540        /// Creates a new fixed byte array with the given random number generator.
541        #[inline]
542        #[doc(alias = "random_using")]
543        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
544        pub fn random_with<R: $crate::private::rand::RngCore + ?Sized>(rng: &mut R) -> Self {
545            Self($crate::FixedBytes::random_with(rng))
546        }
547
548        /// Tries to create a new fixed byte array with the given random number generator.
549        #[inline]
550        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
551        pub fn try_random_with<R: $crate::private::rand::TryRngCore + ?Sized>(
552            rng: &mut R,
553        ) -> $crate::private::Result<Self, R::Error> {
554            $crate::FixedBytes::try_random_with(rng).map(Self)
555        }
556
557        /// Fills this fixed byte array with the given random number generator.
558        #[inline]
559        #[doc(alias = "randomize_using")]
560        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
561        pub fn randomize_with<R: $crate::private::rand::RngCore + ?Sized>(&mut self, rng: &mut R) {
562            self.0.randomize_with(rng);
563        }
564
565        /// Tries to fill this fixed byte array with the given random number generator.
566        #[inline]
567        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
568        pub fn try_randomize_with<R: $crate::private::rand::TryRngCore + ?Sized>(
569            &mut self,
570            rng: &mut R,
571        ) -> $crate::private::Result<(), R::Error> {
572            self.0.try_randomize_with(rng)
573        }
574    };
575
576    ($t:ty) => {
577        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
578        impl $crate::private::rand::distr::Distribution<$t>
579            for $crate::private::rand::distr::StandardUniform
580        {
581            #[inline]
582            fn sample<R: $crate::private::rand::Rng + ?Sized>(&self, rng: &mut R) -> $t {
583                <$t>::random_with(rng)
584            }
585        }
586    };
587}
588
589#[doc(hidden)]
590#[macro_export]
591#[cfg(not(feature = "rand"))]
592macro_rules! impl_rand {
593    ($($t:tt)*) => {};
594}
595
596#[doc(hidden)]
597#[macro_export]
598#[cfg(feature = "rlp")]
599macro_rules! impl_rlp {
600    ($t:ty, $n:literal) => {
601        #[cfg_attr(docsrs, doc(cfg(feature = "rlp")))]
602        impl $crate::private::alloy_rlp::Decodable for $t {
603            #[inline]
604            fn decode(buf: &mut &[u8]) -> $crate::private::alloy_rlp::Result<Self> {
605                $crate::private::alloy_rlp::Decodable::decode(buf).map(Self)
606            }
607        }
608
609        #[cfg_attr(docsrs, doc(cfg(feature = "rlp")))]
610        impl $crate::private::alloy_rlp::Encodable for $t {
611            #[inline]
612            fn length(&self) -> usize {
613                $crate::private::alloy_rlp::Encodable::length(&self.0)
614            }
615
616            #[inline]
617            fn encode(&self, out: &mut dyn $crate::private::alloy_rlp::BufMut) {
618                $crate::private::alloy_rlp::Encodable::encode(&self.0, out)
619            }
620        }
621
622        $crate::private::alloy_rlp::impl_max_encoded_len!($t, {
623            $n + $crate::private::alloy_rlp::length_of_length($n)
624        });
625    };
626}
627
628#[doc(hidden)]
629#[macro_export]
630#[cfg(not(feature = "rlp"))]
631macro_rules! impl_rlp {
632    ($t:ty, $n:literal) => {};
633}
634
635#[doc(hidden)]
636#[macro_export]
637#[cfg(feature = "allocative")]
638macro_rules! impl_allocative {
639    ($t:ty) => {
640        #[cfg_attr(docsrs, doc(cfg(feature = "allocative")))]
641        impl $crate::private::allocative::Allocative for $t {
642            #[inline]
643            fn visit<'a, 'b: 'a>(&self, visitor: &'a mut $crate::private::allocative::Visitor<'b>) {
644                $crate::private::allocative::Allocative::visit(&self.0, visitor)
645            }
646        }
647    };
648}
649
650#[doc(hidden)]
651#[macro_export]
652#[cfg(not(feature = "allocative"))]
653macro_rules! impl_allocative {
654    ($t:ty) => {};
655}
656
657#[doc(hidden)]
658#[macro_export]
659#[cfg(feature = "serde")]
660macro_rules! impl_serde {
661    ($t:ty) => {
662        #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
663        impl $crate::private::serde::Serialize for $t {
664            #[inline]
665            fn serialize<S: $crate::private::serde::Serializer>(
666                &self,
667                serializer: S,
668            ) -> Result<S::Ok, S::Error> {
669                $crate::private::serde::Serialize::serialize(&self.0, serializer)
670            }
671        }
672
673        #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
674        impl<'de> $crate::private::serde::Deserialize<'de> for $t {
675            #[inline]
676            fn deserialize<D: $crate::private::serde::Deserializer<'de>>(
677                deserializer: D,
678            ) -> Result<Self, D::Error> {
679                $crate::private::serde::Deserialize::deserialize(deserializer).map(Self)
680            }
681        }
682    };
683}
684
685#[doc(hidden)]
686#[macro_export]
687#[cfg(not(feature = "serde"))]
688macro_rules! impl_serde {
689    ($t:ty) => {};
690}
691
692#[doc(hidden)]
693#[macro_export]
694#[cfg(feature = "arbitrary")]
695macro_rules! impl_arbitrary {
696    ($t:ty, $n:literal) => {
697        #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
698        impl<'a> $crate::private::arbitrary::Arbitrary<'a> for $t {
699            #[inline]
700            fn arbitrary(u: &mut $crate::private::arbitrary::Unstructured<'a>) -> $crate::private::arbitrary::Result<Self> {
701                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::arbitrary(u).map(Self)
702            }
703
704            #[inline]
705            fn arbitrary_take_rest(u: $crate::private::arbitrary::Unstructured<'a>) -> $crate::private::arbitrary::Result<Self> {
706                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::arbitrary_take_rest(u).map(Self)
707            }
708
709            #[inline]
710            fn size_hint(depth: usize) -> (usize, Option<usize>) {
711                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::size_hint(depth)
712            }
713        }
714
715        #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
716        impl $crate::private::proptest::arbitrary::Arbitrary for $t {
717            type Parameters = <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::Parameters;
718            type Strategy = $crate::private::proptest::strategy::Map<
719                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::Strategy,
720                fn($crate::FixedBytes<$n>) -> Self,
721            >;
722
723            #[inline]
724            fn arbitrary() -> Self::Strategy {
725                use $crate::private::proptest::strategy::Strategy;
726                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::arbitrary()
727                    .prop_map(Self)
728            }
729
730            #[inline]
731            fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
732                use $crate::private::proptest::strategy::Strategy;
733                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::arbitrary_with(args)
734                    .prop_map(Self)
735            }
736        }
737    };
738}
739
740#[doc(hidden)]
741#[macro_export]
742#[cfg(not(feature = "arbitrary"))]
743macro_rules! impl_arbitrary {
744    ($t:ty, $n:literal) => {};
745}
746
747#[doc(hidden)]
748#[macro_export]
749#[cfg(feature = "diesel")]
750macro_rules! impl_diesel {
751    ($t:ty, $n:literal) => {
752        const _: () = {
753            use $crate::private::diesel::{
754                backend::Backend,
755                deserialize::{FromSql, Result as DeserResult},
756                expression::AsExpression,
757                internal::derives::as_expression::Bound,
758                query_builder::bind_collector::RawBytesBindCollector,
759                serialize::{Output, Result as SerResult, ToSql},
760                sql_types::{Binary, Nullable, SingleValue},
761                Queryable,
762            };
763
764            impl<Db> ToSql<Binary, Db> for $t
765            where
766                for<'c> Db: Backend<BindCollector<'c> = RawBytesBindCollector<Db>>,
767            {
768                fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Db>) -> SerResult {
769                    <$crate::FixedBytes<$n> as ToSql<Binary, Db>>::to_sql(&self.0, out)
770                }
771            }
772
773            impl<Db> FromSql<Binary, Db> for $t
774            where
775                Db: Backend,
776                *const [u8]: FromSql<Binary, Db>,
777            {
778                fn from_sql(bytes: Db::RawValue<'_>) -> DeserResult<Self> {
779                    <$crate::FixedBytes<$n> as FromSql<Binary, Db>>::from_sql(bytes).map(Self)
780                }
781            }
782
783            // Note: the following impls are equivalent to the expanded derive macro produced by
784            // #[derive(diesel::AsExpression)]
785            impl<Db> ToSql<Nullable<Binary>, Db> for $t
786            where
787                for<'c> Db: Backend<BindCollector<'c> = RawBytesBindCollector<Db>>,
788            {
789                fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Db>) -> SerResult {
790                    <$crate::FixedBytes<$n> as ToSql<Nullable<Binary>, Db>>::to_sql(&self.0, out)
791                }
792            }
793
794            impl AsExpression<Binary> for $t {
795                type Expression = Bound<Binary, Self>;
796                fn as_expression(self) -> Self::Expression {
797                    Bound::new(self)
798                }
799            }
800
801            impl AsExpression<Nullable<Binary>> for $t {
802                type Expression = Bound<Nullable<Binary>, Self>;
803                fn as_expression(self) -> Self::Expression {
804                    Bound::new(self)
805                }
806            }
807
808            impl AsExpression<Binary> for &$t {
809                type Expression = Bound<Binary, Self>;
810                fn as_expression(self) -> Self::Expression {
811                    Bound::new(self)
812                }
813            }
814
815            impl AsExpression<Nullable<Binary>> for &$t {
816                type Expression = Bound<Nullable<Binary>, Self>;
817                fn as_expression(self) -> Self::Expression {
818                    Bound::new(self)
819                }
820            }
821
822            impl AsExpression<Binary> for &&$t {
823                type Expression = Bound<Binary, Self>;
824                fn as_expression(self) -> Self::Expression {
825                    Bound::new(self)
826                }
827            }
828
829            impl AsExpression<Nullable<Binary>> for &&$t {
830                type Expression = Bound<Nullable<Binary>, Self>;
831                fn as_expression(self) -> Self::Expression {
832                    Bound::new(self)
833                }
834            }
835
836            // Note: the following impl is equivalent to the expanded derive macro produced by
837            // #[derive(diesel::Queryable)]
838            impl<Db, St> Queryable<St, Db> for $t
839            where
840                Db: Backend,
841                St: SingleValue,
842                Self: FromSql<St, Db>,
843            {
844                type Row = Self;
845                fn build(row: Self::Row) -> DeserResult<Self> {
846                    Ok(row)
847                }
848            }
849        };
850    };
851}
852
853#[doc(hidden)]
854#[macro_export]
855#[cfg(not(feature = "diesel"))]
856macro_rules! impl_diesel {
857    ($t:ty, $n:literal) => {};
858}
859
860macro_rules! fixed_bytes_macros {
861    ($d:tt $($(#[$attr:meta])* macro $name:ident($ty:ident $($rest:tt)*);)*) => {$(
862        /// Converts a sequence of string literals containing hex-encoded data
863        #[doc = concat!(
864            "into a new [`", stringify!($ty), "`][crate::", stringify!($ty), "] at compile time.\n",
865        )]
866        ///
867        /// If the input is empty, a zero-initialized array is returned.
868        ///
869        /// See [`hex!`](crate::hex!) for more information.
870        ///
871        /// # Examples
872        ///
873        /// ```
874        #[doc = concat!("use alloy_primitives::{", stringify!($name), ", ", stringify!($ty), "};")]
875        ///
876        #[doc = concat!("const ZERO: ", stringify!($ty $($rest)*), " = ", stringify!($name), "!();")]
877        #[doc = concat!("assert_eq!(ZERO, ", stringify!($ty), "::ZERO);")]
878        ///
879        /// # stringify!(
880        #[doc = concat!("let byte_array: ", stringify!($ty), " = ", stringify!($name), "!(\"0x0123abcd…\");")]
881        /// # );
882        /// ```
883        $(#[$attr])*
884        #[macro_export]
885        macro_rules! $name {
886            () => {
887                $crate::$ty::ZERO
888            };
889
890            ($d ($d t:tt)+) => {
891                $crate::$ty::new($crate::hex!($d ($d t)+))
892            };
893        }
894    )*};
895}
896
897fixed_bytes_macros! { $
898    macro address(Address);
899
900    macro b64(B64);
901
902    macro b128(B128);
903
904    macro b256(B256);
905
906    macro b512(B512);
907
908    macro bloom(Bloom);
909
910    macro fixed_bytes(FixedBytes<0>); // <0> is just for the doctest
911}
912
913/// Converts a sequence of string literals containing hex-encoded data into a
914/// new [`Bytes`][crate::Bytes] at compile time.
915///
916/// If the input is empty, an empty instance is returned.
917///
918/// See [`hex!`](crate::hex!) for more information.
919///
920/// # Examples
921///
922/// ```
923/// use alloy_primitives::{bytes, Bytes};
924///
925/// static MY_BYTES: Bytes = bytes!("0x0123" "0xabcd");
926/// assert_eq!(MY_BYTES, Bytes::from(&[0x01, 0x23, 0xab, 0xcd]));
927/// ```
928#[macro_export]
929macro_rules! bytes {
930    () => {
931        $crate::Bytes::new()
932    };
933
934    ($($s:literal)+) => {const {
935        $crate::Bytes::from_static(&$crate::hex!($($s)+))
936    }};
937
938    [$($inner:expr),+ $(,)?] => {const {
939        $crate::Bytes::from_static(&[$($inner),+])
940    }};
941
942    [$inner:expr; $size:literal] => {const {
943        $crate::Bytes::from_static(&[$inner; $size])
944    }};
945}
946
947#[cfg(test)]
948mod tests {
949    use crate::{hex, Address, Bytes, FixedBytes};
950
951    #[test]
952    fn bytes_macros() {
953        static B1: Bytes = bytes!("010203040506070809");
954        static B2: Bytes = bytes![1, 2, 3, 4, 5, 6, 7, 8, 9];
955        static B3: Bytes = bytes![1, 2, 3, 4, 5, 6, 7, 8, 9,];
956
957        assert_eq!(B1, B2);
958        assert_eq!(B1, B3);
959
960        static B4: Bytes = bytes!("0000");
961        static B5: Bytes = bytes![0; 2];
962        static B6: Bytes = bytes![0, 0];
963        assert_eq!(B4, B5);
964        assert_eq!(B4, B6);
965    }
966
967    #[test]
968    fn fixed_byte_macros() {
969        const A0: Address = address!();
970        assert_eq!(A0, Address::ZERO);
971
972        const A1: Address = address!("0x0102030405060708090a0b0c0d0e0f1011121314");
973        const A2: Address = Address(fixed_bytes!("0x0102030405060708090a0b0c0d0e0f1011121314"));
974        const A3: Address = Address(FixedBytes(hex!("0x0102030405060708090a0b0c0d0e0f1011121314")));
975        assert_eq!(A1, A2);
976        assert_eq!(A1, A3);
977        assert_eq!(A1, hex!("0x0102030405060708090a0b0c0d0e0f1011121314"));
978
979        static B: Bytes = bytes!("0x112233");
980        assert_eq!(B[..], [0x11, 0x22, 0x33]);
981
982        static EMPTY_BYTES1: Bytes = bytes!();
983        static EMPTY_BYTES2: Bytes = bytes!("");
984        assert!(EMPTY_BYTES1.is_empty());
985        assert_eq!(EMPTY_BYTES1, Bytes::new());
986        assert_eq!(EMPTY_BYTES1, EMPTY_BYTES2);
987    }
988}