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        $crate::impl_fb_traits!($name, $n);
182        $crate::impl_rlp!($name, $n);
183        $crate::impl_serde!($name);
184        $crate::impl_allocative!($name);
185        $crate::impl_arbitrary!($name, $n);
186        $crate::impl_rand!($name);
187        $crate::impl_diesel!($name, $n);
188
189        impl $name {
190            /// Array of Zero bytes.
191            pub const ZERO: Self = Self($crate::FixedBytes::ZERO);
192
193            /// Wraps the given byte array in this type.
194            #[inline]
195            pub const fn new(bytes: [u8; $n]) -> Self {
196                Self($crate::FixedBytes(bytes))
197            }
198
199            /// Creates a new byte array with the last byte set to `x`.
200            #[inline]
201            pub const fn with_last_byte(x: u8) -> Self {
202                Self($crate::FixedBytes::with_last_byte(x))
203            }
204
205            /// Creates a new byte array where all bytes are set to `byte`.
206            #[inline]
207            pub const fn repeat_byte(byte: u8) -> Self {
208                Self($crate::FixedBytes::repeat_byte(byte))
209            }
210
211            /// Returns the size of this array in bytes.
212            #[inline]
213            pub const fn len_bytes() -> usize {
214                $n
215            }
216
217            $crate::impl_getrandom!();
218            $crate::impl_rand!();
219
220            /// Create a new byte array from the given slice `src`.
221            ///
222            /// For a fallible version, use the `TryFrom<&[u8]>` implementation.
223            ///
224            /// # Note
225            ///
226            /// The given bytes are interpreted in big endian order.
227            ///
228            /// # Panics
229            ///
230            /// If the length of `src` and the number of bytes in `Self` do not match.
231            #[inline]
232            #[track_caller]
233            pub fn from_slice(src: &[u8]) -> Self {
234                match Self::try_from(src) {
235                    Ok(x) => x,
236                    Err(_) => panic!("cannot convert a slice of length {} to {}", src.len(), stringify!($name)),
237                }
238            }
239
240            /// Create a new byte array from the given slice `src`, left-padding it
241            /// with zeroes if necessary.
242            ///
243            /// # Note
244            ///
245            /// The given bytes are interpreted in big endian order.
246            ///
247            /// # Panics
248            ///
249            /// Panics if `src.len() > N`.
250            #[inline]
251            #[track_caller]
252            pub fn left_padding_from(value: &[u8]) -> Self {
253                Self($crate::FixedBytes::left_padding_from(value))
254            }
255
256            /// Create a new byte array from the given slice `src`, right-padding it
257            /// with zeroes if necessary.
258            ///
259            /// # Note
260            ///
261            /// The given bytes are interpreted in big endian order.
262            ///
263            /// # Panics
264            ///
265            /// Panics if `src.len() > N`.
266            #[inline]
267            #[track_caller]
268            pub fn right_padding_from(value: &[u8]) -> Self {
269                Self($crate::FixedBytes::right_padding_from(value))
270            }
271
272            /// Returns the inner bytes array.
273            #[inline]
274            pub const fn into_array(self) -> [u8; $n] {
275                self.0 .0
276            }
277
278            /// Returns `true` if all bits set in `b` are also set in `self`.
279            #[inline]
280            pub fn covers(&self, b: &Self) -> bool {
281                &(*b & *self) == b
282            }
283
284            /// Compile-time equality. NOT constant-time equality.
285            pub const fn const_eq(&self, other: &Self) -> bool {
286                self.0.const_eq(&other.0)
287            }
288
289            /// Computes the bitwise AND of two `FixedBytes`.
290            pub const fn bit_and(self, rhs: Self) -> Self {
291                Self(self.0.bit_and(rhs.0))
292            }
293
294            /// Computes the bitwise OR of two `FixedBytes`.
295            pub const fn bit_or(self, rhs: Self) -> Self {
296                Self(self.0.bit_or(rhs.0))
297            }
298
299            /// Computes the bitwise XOR of two `FixedBytes`.
300            pub const fn bit_xor(self, rhs: Self) -> Self {
301                Self(self.0.bit_xor(rhs.0))
302            }
303        }
304    };
305}
306
307// Extra traits that cannot be derived automatically
308#[doc(hidden)]
309#[macro_export]
310macro_rules! impl_fb_traits {
311    (impl<$($const:ident)?> Borrow<$t:ty> for $b:ty) => {
312        impl<$($const N: usize)?> $crate::private::Borrow<$t> for $b {
313            #[inline]
314            fn borrow(&self) -> &$t {
315                $crate::private::Borrow::borrow(&self.0)
316            }
317        }
318    };
319
320    (impl<$($const:ident)?> BorrowMut<$t:ty> for $b:ty) => {
321        impl<$($const N: usize)?> $crate::private::BorrowMut<$t> for $b {
322            #[inline]
323            fn borrow_mut(&mut self) -> &mut $t {
324                $crate::private::BorrowMut::borrow_mut(&mut self.0)
325            }
326        }
327    };
328
329    (unsafe impl<$lt:lifetime, $($const:ident)?> From<$a:ty> for $b:ty) => {
330        impl<$lt, $($const N: usize)?> $crate::private::From<$a> for $b {
331            #[inline]
332            #[allow(unsafe_code)]
333            fn from(value: $a) -> $b {
334                // SAFETY: guaranteed by caller
335                unsafe { $crate::private::core::mem::transmute::<$a, $b>(value) }
336            }
337        }
338    };
339
340    (impl<$($const:ident)?> cmp::$tr:ident<$a:ty> for $b:ty where fn $fn:ident -> $ret:ty $(, [$e:expr])?) => {
341        impl<$($const N: usize)?> $crate::private::$tr<$a> for $b {
342            #[inline]
343            fn $fn(&self, other: &$a) -> $ret {
344                $crate::private::$tr::$fn(&self.0 $([$e])?, other)
345            }
346        }
347
348        impl<$($const N: usize)?> $crate::private::$tr<$b> for $a {
349            #[inline]
350            fn $fn(&self, other: &$b) -> $ret {
351                $crate::private::$tr::$fn(self, &other.0 $([$e])?)
352            }
353        }
354
355        impl<$($const N: usize)?> $crate::private::$tr<&$a> for $b {
356            #[inline]
357            fn $fn(&self, other: &&$a) -> $ret {
358                $crate::private::$tr::$fn(&self.0 $([$e])?, *other)
359            }
360        }
361
362        impl<$($const N: usize)?> $crate::private::$tr<$b> for &$a {
363            #[inline]
364            fn $fn(&self, other: &$b) -> $ret {
365                $crate::private::$tr::$fn(*self, &other.0 $([$e])?)
366            }
367        }
368
369        impl<$($const N: usize)?> $crate::private::$tr<$a> for &$b {
370            #[inline]
371            fn $fn(&self, other: &$a) -> $ret {
372                $crate::private::$tr::$fn(&self.0 $([$e])?, other)
373            }
374        }
375
376        impl<$($const N: usize)?> $crate::private::$tr<&$b> for $a {
377            #[inline]
378            fn $fn(&self, other: &&$b) -> $ret {
379                $crate::private::$tr::$fn(self, &other.0 $([$e])?)
380            }
381        }
382    };
383
384    ($t:ty, $n:tt $(, $const:ident)?) => {
385        // Borrow is not automatically implemented for references
386        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for $t);
387        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for &$t);
388        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8]>        for &mut $t);
389        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for $t);
390        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for &$t);
391        $crate::impl_fb_traits!(impl<$($const)?> Borrow<[u8; $n]>    for &mut $t);
392
393        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8]>     for $t);
394        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8]>     for &mut $t);
395        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8; $n]> for $t);
396        $crate::impl_fb_traits!(impl<$($const)?> BorrowMut<[u8; $n]> for &mut $t);
397
398        // Implement conversion traits for references with `mem::transmute`
399        // SAFETY: `repr(transparent)`
400        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a [u8; $n]>     for &'a $t);
401        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut [u8; $n]> for &'a $t);
402        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut [u8; $n]> for &'a mut $t);
403
404        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a $t>           for &'a [u8; $n]);
405        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut $t>       for &'a [u8; $n]);
406        $crate::impl_fb_traits!(unsafe impl<'a, $($const)?> From<&'a mut $t>       for &'a mut [u8; $n]);
407
408        // Implement PartialEq, PartialOrd, with slice and array
409        $crate::impl_fb_traits!(impl<$($const)?> cmp::PartialEq<[u8]> for $t where fn eq -> bool);
410        $crate::impl_fb_traits!(impl<$($const)?> cmp::PartialEq<[u8; $n]> for $t where fn eq -> bool);
411        $crate::impl_fb_traits!(
412            impl<$($const)?> cmp::PartialOrd<[u8]> for $t
413            where
414                fn partial_cmp -> $crate::private::Option<$crate::private::Ordering>,
415                [..] // slices $t
416        );
417
418        impl<$($const N: usize)?> $crate::hex::FromHex for $t {
419            type Error = $crate::hex::FromHexError;
420
421            #[inline]
422            fn from_hex<T: $crate::private::AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
423                $crate::hex::decode_to_array(hex).map(Self::new)
424            }
425        }
426    };
427}
428
429#[doc(hidden)]
430#[macro_export]
431#[cfg(feature = "getrandom")]
432macro_rules! impl_getrandom {
433    () => {
434        /// Creates a new fixed byte array with the default cryptographic random number
435        /// generator.
436        ///
437        /// This is `rand::thread_rng` if the "rand" and "std" features are enabled, otherwise
438        /// it uses `getrandom::getrandom`. Both are cryptographically secure.
439        #[inline]
440        #[track_caller]
441        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
442        pub fn random() -> Self {
443            Self($crate::FixedBytes::random())
444        }
445
446        /// Tries to create a new fixed byte array with the default cryptographic random number
447        /// generator.
448        ///
449        /// See [`random`](Self::random) for more details.
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 the default cryptographic random number generator.
457        ///
458        /// See [`random`](Self::random) for more details.
459        #[inline]
460        #[track_caller]
461        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
462        pub fn randomize(&mut self) {
463            self.0.randomize();
464        }
465
466        /// Tries to fill this fixed byte array with the default cryptographic random number
467        /// generator.
468        ///
469        /// See [`random`](Self::random) for more details.
470        #[inline]
471        #[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
472        pub fn try_randomize(
473            &mut self,
474        ) -> $crate::private::Result<(), $crate::private::getrandom::Error> {
475            self.0.try_randomize()
476        }
477    };
478}
479
480#[doc(hidden)]
481#[macro_export]
482#[cfg(not(feature = "getrandom"))]
483macro_rules! impl_getrandom {
484    () => {};
485}
486
487#[doc(hidden)]
488#[macro_export]
489#[cfg(feature = "rand")]
490macro_rules! impl_rand {
491    () => {
492        /// Creates a new fixed byte array with the given random number generator.
493        #[inline]
494        #[doc(alias = "random_using")]
495        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
496        pub fn random_with<R: $crate::private::rand::RngCore + ?Sized>(rng: &mut R) -> Self {
497            Self($crate::FixedBytes::random_with(rng))
498        }
499
500        /// Tries to create a new fixed byte array with the given random number generator.
501        #[inline]
502        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
503        pub fn try_random_with<R: $crate::private::rand::TryRngCore + ?Sized>(
504            rng: &mut R,
505        ) -> $crate::private::Result<Self, R::Error> {
506            $crate::FixedBytes::try_random_with(rng).map(Self)
507        }
508
509        /// Fills this fixed byte array with the given random number generator.
510        #[inline]
511        #[doc(alias = "randomize_using")]
512        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
513        pub fn randomize_with<R: $crate::private::rand::RngCore + ?Sized>(&mut self, rng: &mut R) {
514            self.0.randomize_with(rng);
515        }
516
517        /// Tries to fill this fixed byte array with the given random number generator.
518        #[inline]
519        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
520        pub fn try_randomize_with<R: $crate::private::rand::TryRngCore + ?Sized>(
521            &mut self,
522            rng: &mut R,
523        ) -> $crate::private::Result<(), R::Error> {
524            self.0.try_randomize_with(rng)
525        }
526    };
527
528    ($t:ty) => {
529        #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
530        impl $crate::private::rand::distr::Distribution<$t>
531            for $crate::private::rand::distr::StandardUniform
532        {
533            #[inline]
534            fn sample<R: $crate::private::rand::Rng + ?Sized>(&self, rng: &mut R) -> $t {
535                <$t>::random_with(rng)
536            }
537        }
538    };
539}
540
541#[doc(hidden)]
542#[macro_export]
543#[cfg(not(feature = "rand"))]
544macro_rules! impl_rand {
545    ($($t:tt)*) => {};
546}
547
548#[doc(hidden)]
549#[macro_export]
550#[cfg(feature = "rlp")]
551macro_rules! impl_rlp {
552    ($t:ty, $n:literal) => {
553        #[cfg_attr(docsrs, doc(cfg(feature = "rlp")))]
554        impl $crate::private::alloy_rlp::Decodable for $t {
555            #[inline]
556            fn decode(buf: &mut &[u8]) -> $crate::private::alloy_rlp::Result<Self> {
557                $crate::private::alloy_rlp::Decodable::decode(buf).map(Self)
558            }
559        }
560
561        #[cfg_attr(docsrs, doc(cfg(feature = "rlp")))]
562        impl $crate::private::alloy_rlp::Encodable for $t {
563            #[inline]
564            fn length(&self) -> usize {
565                $crate::private::alloy_rlp::Encodable::length(&self.0)
566            }
567
568            #[inline]
569            fn encode(&self, out: &mut dyn $crate::private::alloy_rlp::BufMut) {
570                $crate::private::alloy_rlp::Encodable::encode(&self.0, out)
571            }
572        }
573
574        $crate::private::alloy_rlp::impl_max_encoded_len!($t, {
575            $n + $crate::private::alloy_rlp::length_of_length($n)
576        });
577    };
578}
579
580#[doc(hidden)]
581#[macro_export]
582#[cfg(not(feature = "rlp"))]
583macro_rules! impl_rlp {
584    ($t:ty, $n:literal) => {};
585}
586
587#[doc(hidden)]
588#[macro_export]
589#[cfg(feature = "allocative")]
590macro_rules! impl_allocative {
591    ($t:ty) => {
592        #[cfg_attr(docsrs, doc(cfg(feature = "allocative")))]
593        impl $crate::private::allocative::Allocative for $t {
594            #[inline]
595            fn visit<'a, 'b: 'a>(&self, visitor: &'a mut $crate::private::allocative::Visitor<'b>) {
596                $crate::private::allocative::Allocative::visit(&self.0, visitor)
597            }
598        }
599    };
600}
601
602#[doc(hidden)]
603#[macro_export]
604#[cfg(not(feature = "allocative"))]
605macro_rules! impl_allocative {
606    ($t:ty) => {};
607}
608
609#[doc(hidden)]
610#[macro_export]
611#[cfg(feature = "serde")]
612macro_rules! impl_serde {
613    ($t:ty) => {
614        #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
615        impl $crate::private::serde::Serialize for $t {
616            #[inline]
617            fn serialize<S: $crate::private::serde::Serializer>(
618                &self,
619                serializer: S,
620            ) -> Result<S::Ok, S::Error> {
621                $crate::private::serde::Serialize::serialize(&self.0, serializer)
622            }
623        }
624
625        #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
626        impl<'de> $crate::private::serde::Deserialize<'de> for $t {
627            #[inline]
628            fn deserialize<D: $crate::private::serde::Deserializer<'de>>(
629                deserializer: D,
630            ) -> Result<Self, D::Error> {
631                $crate::private::serde::Deserialize::deserialize(deserializer).map(Self)
632            }
633        }
634    };
635}
636
637#[doc(hidden)]
638#[macro_export]
639#[cfg(not(feature = "serde"))]
640macro_rules! impl_serde {
641    ($t:ty) => {};
642}
643
644#[doc(hidden)]
645#[macro_export]
646#[cfg(feature = "arbitrary")]
647macro_rules! impl_arbitrary {
648    ($t:ty, $n:literal) => {
649        #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
650        impl<'a> $crate::private::arbitrary::Arbitrary<'a> for $t {
651            #[inline]
652            fn arbitrary(u: &mut $crate::private::arbitrary::Unstructured<'a>) -> $crate::private::arbitrary::Result<Self> {
653                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::arbitrary(u).map(Self)
654            }
655
656            #[inline]
657            fn arbitrary_take_rest(u: $crate::private::arbitrary::Unstructured<'a>) -> $crate::private::arbitrary::Result<Self> {
658                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::arbitrary_take_rest(u).map(Self)
659            }
660
661            #[inline]
662            fn size_hint(depth: usize) -> (usize, Option<usize>) {
663                <$crate::FixedBytes<$n> as $crate::private::arbitrary::Arbitrary>::size_hint(depth)
664            }
665        }
666
667        #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
668        impl $crate::private::proptest::arbitrary::Arbitrary for $t {
669            type Parameters = <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::Parameters;
670            type Strategy = $crate::private::proptest::strategy::Map<
671                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::Strategy,
672                fn($crate::FixedBytes<$n>) -> Self,
673            >;
674
675            #[inline]
676            fn arbitrary() -> Self::Strategy {
677                use $crate::private::proptest::strategy::Strategy;
678                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::arbitrary()
679                    .prop_map(Self)
680            }
681
682            #[inline]
683            fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
684                use $crate::private::proptest::strategy::Strategy;
685                <$crate::FixedBytes<$n> as $crate::private::proptest::arbitrary::Arbitrary>::arbitrary_with(args)
686                    .prop_map(Self)
687            }
688        }
689    };
690}
691
692#[doc(hidden)]
693#[macro_export]
694#[cfg(not(feature = "arbitrary"))]
695macro_rules! impl_arbitrary {
696    ($t:ty, $n:literal) => {};
697}
698
699#[doc(hidden)]
700#[macro_export]
701#[cfg(feature = "diesel")]
702macro_rules! impl_diesel {
703    ($t:ty, $n:literal) => {
704        const _: () = {
705            use $crate::private::diesel::{
706                backend::Backend,
707                deserialize::{FromSql, Result as DeserResult},
708                expression::AsExpression,
709                internal::derives::as_expression::Bound,
710                query_builder::bind_collector::RawBytesBindCollector,
711                serialize::{Output, Result as SerResult, ToSql},
712                sql_types::{Binary, Nullable, SingleValue},
713                Queryable,
714            };
715
716            impl<Db> ToSql<Binary, Db> for $t
717            where
718                for<'c> Db: Backend<BindCollector<'c> = RawBytesBindCollector<Db>>,
719            {
720                fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Db>) -> SerResult {
721                    <$crate::FixedBytes<$n> as ToSql<Binary, Db>>::to_sql(&self.0, out)
722                }
723            }
724
725            impl<Db> FromSql<Binary, Db> for $t
726            where
727                Db: Backend,
728                *const [u8]: FromSql<Binary, Db>,
729            {
730                fn from_sql(bytes: Db::RawValue<'_>) -> DeserResult<Self> {
731                    <$crate::FixedBytes<$n> as FromSql<Binary, Db>>::from_sql(bytes).map(Self)
732                }
733            }
734
735            // Note: the following impls are equivalent to the expanded derive macro produced by
736            // #[derive(diesel::AsExpression)]
737            impl<Db> ToSql<Nullable<Binary>, Db> for $t
738            where
739                for<'c> Db: Backend<BindCollector<'c> = RawBytesBindCollector<Db>>,
740            {
741                fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Db>) -> SerResult {
742                    <$crate::FixedBytes<$n> as ToSql<Nullable<Binary>, Db>>::to_sql(&self.0, out)
743                }
744            }
745
746            impl AsExpression<Binary> for $t {
747                type Expression = Bound<Binary, Self>;
748                fn as_expression(self) -> Self::Expression {
749                    Bound::new(self)
750                }
751            }
752
753            impl AsExpression<Nullable<Binary>> for $t {
754                type Expression = Bound<Nullable<Binary>, Self>;
755                fn as_expression(self) -> Self::Expression {
756                    Bound::new(self)
757                }
758            }
759
760            impl AsExpression<Binary> for &$t {
761                type Expression = Bound<Binary, Self>;
762                fn as_expression(self) -> Self::Expression {
763                    Bound::new(self)
764                }
765            }
766
767            impl AsExpression<Nullable<Binary>> for &$t {
768                type Expression = Bound<Nullable<Binary>, Self>;
769                fn as_expression(self) -> Self::Expression {
770                    Bound::new(self)
771                }
772            }
773
774            impl AsExpression<Binary> for &&$t {
775                type Expression = Bound<Binary, Self>;
776                fn as_expression(self) -> Self::Expression {
777                    Bound::new(self)
778                }
779            }
780
781            impl AsExpression<Nullable<Binary>> for &&$t {
782                type Expression = Bound<Nullable<Binary>, Self>;
783                fn as_expression(self) -> Self::Expression {
784                    Bound::new(self)
785                }
786            }
787
788            // Note: the following impl is equivalent to the expanded derive macro produced by
789            // #[derive(diesel::Queryable)]
790            impl<Db, St> Queryable<St, Db> for $t
791            where
792                Db: Backend,
793                St: SingleValue,
794                Self: FromSql<St, Db>,
795            {
796                type Row = Self;
797                fn build(row: Self::Row) -> DeserResult<Self> {
798                    Ok(row)
799                }
800            }
801        };
802    };
803}
804
805#[doc(hidden)]
806#[macro_export]
807#[cfg(not(feature = "diesel"))]
808macro_rules! impl_diesel {
809    ($t:ty, $n:literal) => {};
810}
811
812macro_rules! fixed_bytes_macros {
813    ($d:tt $($(#[$attr:meta])* macro $name:ident($ty:ident $($rest:tt)*);)*) => {$(
814        /// Converts a sequence of string literals containing hex-encoded data
815        #[doc = concat!(
816            "into a new [`", stringify!($ty), "`][crate::", stringify!($ty), "] at compile time.\n",
817        )]
818        ///
819        /// If the input is empty, a zero-initialized array is returned.
820        ///
821        /// See [`hex!`](crate::hex!) for more information.
822        ///
823        /// # Examples
824        ///
825        /// ```
826        #[doc = concat!("use alloy_primitives::{", stringify!($name), ", ", stringify!($ty), "};")]
827        ///
828        #[doc = concat!("const ZERO: ", stringify!($ty $($rest)*), " = ", stringify!($name), "!();")]
829        #[doc = concat!("assert_eq!(ZERO, ", stringify!($ty), "::ZERO);")]
830        ///
831        /// # stringify!(
832        #[doc = concat!("let byte_array: ", stringify!($ty), " = ", stringify!($name), "!(\"0x0123abcd…\");")]
833        /// # );
834        /// ```
835        $(#[$attr])*
836        #[macro_export]
837        macro_rules! $name {
838            () => {
839                $crate::$ty::ZERO
840            };
841
842            ($d ($d t:tt)+) => {
843                $crate::$ty::new($crate::hex!($d ($d t)+))
844            };
845        }
846    )*};
847}
848
849fixed_bytes_macros! { $
850    macro address(Address);
851
852    macro b64(B64);
853
854    macro b128(B128);
855
856    macro b256(B256);
857
858    macro b512(B512);
859
860    macro bloom(Bloom);
861
862    macro fixed_bytes(FixedBytes<0>); // <0> is just for the doctest
863}
864
865/// Converts a sequence of string literals containing hex-encoded data into a
866/// new [`Bytes`][crate::Bytes] at compile time.
867///
868/// If the input is empty, an empty instance is returned.
869///
870/// See [`hex!`](crate::hex!) for more information.
871///
872/// # Examples
873///
874/// ```
875/// use alloy_primitives::{bytes, Bytes};
876///
877/// static MY_BYTES: Bytes = bytes!("0x0123" "0xabcd");
878/// assert_eq!(MY_BYTES, Bytes::from(&[0x01, 0x23, 0xab, 0xcd]));
879/// ```
880#[macro_export]
881macro_rules! bytes {
882    () => {
883        $crate::Bytes::new()
884    };
885
886    ($($s:literal)+) => {const {
887        $crate::Bytes::from_static(&$crate::hex!($($s)+))
888    }};
889
890    [$($inner:expr),+ $(,)?] => {const {
891        $crate::Bytes::from_static(&[$($inner),+])
892    }};
893
894    [$inner:expr; $size:literal] => {const {
895        $crate::Bytes::from_static(&[$inner; $size])
896    }};
897}
898
899#[cfg(test)]
900mod tests {
901    use crate::{hex, Address, Bytes, FixedBytes};
902
903    #[test]
904    fn bytes_macros() {
905        static B1: Bytes = bytes!("010203040506070809");
906        static B2: Bytes = bytes![1, 2, 3, 4, 5, 6, 7, 8, 9];
907        static B3: Bytes = bytes![1, 2, 3, 4, 5, 6, 7, 8, 9,];
908
909        assert_eq!(B1, B2);
910        assert_eq!(B1, B3);
911
912        static B4: Bytes = bytes!("0000");
913        static B5: Bytes = bytes![0; 2];
914        static B6: Bytes = bytes![0, 0];
915        assert_eq!(B4, B5);
916        assert_eq!(B4, B6);
917    }
918
919    #[test]
920    fn fixed_byte_macros() {
921        const A0: Address = address!();
922        assert_eq!(A0, Address::ZERO);
923
924        const A1: Address = address!("0x0102030405060708090a0b0c0d0e0f1011121314");
925        const A2: Address = Address(fixed_bytes!("0x0102030405060708090a0b0c0d0e0f1011121314"));
926        const A3: Address = Address(FixedBytes(hex!("0x0102030405060708090a0b0c0d0e0f1011121314")));
927        assert_eq!(A1, A2);
928        assert_eq!(A1, A3);
929        assert_eq!(A1, hex!("0x0102030405060708090a0b0c0d0e0f1011121314"));
930
931        static B: Bytes = bytes!("0x112233");
932        assert_eq!(B[..], [0x11, 0x22, 0x33]);
933
934        static EMPTY_BYTES1: Bytes = bytes!();
935        static EMPTY_BYTES2: Bytes = bytes!("");
936        assert!(EMPTY_BYTES1.is_empty());
937        assert_eq!(EMPTY_BYTES1, Bytes::new());
938        assert_eq!(EMPTY_BYTES1, EMPTY_BYTES2);
939    }
940}