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