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