Skip to main content

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