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