alloy_primitives/bits/
macros.rs

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