ethers_fixed_hash/
hash.rs1#[macro_export(local_inner_macros)]
42macro_rules! construct_fixed_hash {
43 ( $(#[$attr:meta])* $visibility:vis struct $name:ident ( $n_bytes:expr ); ) => {
44 #[repr(C)]
45 $(#[$attr])*
46 $visibility struct $name (pub [u8; $n_bytes]);
47
48 impl From<[u8; $n_bytes]> for $name {
49 #[inline]
55 fn from(bytes: [u8; $n_bytes]) -> Self {
56 $name(bytes)
57 }
58 }
59
60 impl<'a> From<&'a [u8; $n_bytes]> for $name {
61 #[inline]
68 fn from(bytes: &'a [u8; $n_bytes]) -> Self {
69 $name(*bytes)
70 }
71 }
72
73 impl<'a> From<&'a mut [u8; $n_bytes]> for $name {
74 #[inline]
81 fn from(bytes: &'a mut [u8; $n_bytes]) -> Self {
82 $name(*bytes)
83 }
84 }
85
86 impl<'a> TryFrom<&'a str> for $name {
87 type Error = $crate::rustc_hex::FromHexError;
88
89 fn try_from(value: &'a str) -> Result<Self, Self::Error> {
90 let input = value.strip_prefix("0x").unwrap_or(value);
91 let mut iter = $crate::rustc_hex::FromHexIter::new(input);
92 let mut result = Self::zero();
93 for byte in result.as_mut() {
94 *byte = iter.next().ok_or(Self::Error::InvalidHexLength)??;
95 }
96 if iter.next().is_some() {
97 return Err(Self::Error::InvalidHexLength);
98 }
99 Ok(result)
100 }
101 }
102
103 impl TryFrom<String> for $name {
104 type Error = $crate::rustc_hex::FromHexError;
105
106 fn try_from(value: String) -> Result<Self, Self::Error> {
107
108 let input = value.strip_prefix("0x").unwrap_or(&value);
109
110 let mut iter = $crate::rustc_hex::FromHexIter::new(input);
111 let mut result = Self::zero();
112 for byte in result.as_mut() {
113 *byte = iter.next().ok_or(Self::Error::InvalidHexLength)??;
114 }
115 if iter.next().is_some() {
116 return Err(Self::Error::InvalidHexLength);
117 }
118 Ok(result)
119 }
120 }
121
122 impl From<$name> for [u8; $n_bytes] {
123 #[inline]
124 fn from(s: $name) -> Self {
125 s.0
126 }
127 }
128
129 impl AsRef<[u8]> for $name {
130 #[inline]
131 fn as_ref(&self) -> &[u8] {
132 self.as_bytes()
133 }
134 }
135
136 impl AsMut<[u8]> for $name {
137 #[inline]
138 fn as_mut(&mut self) -> &mut [u8] {
139 self.as_bytes_mut()
140 }
141 }
142
143 impl $name {
144 #[inline]
146 pub const fn repeat_byte(byte: u8) -> $name {
147 $name([byte; $n_bytes])
148 }
149
150 #[inline]
152 pub const fn zero() -> $name {
153 $name::repeat_byte(0u8)
154 }
155
156 #[inline]
158 pub const fn len_bytes() -> usize {
159 $n_bytes
160 }
161
162 #[inline]
164 pub fn as_bytes(&self) -> &[u8] {
165 &self.0
166 }
167
168 #[inline]
170 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
171 &mut self.0
172 }
173
174 #[inline]
176 pub const fn as_fixed_bytes(&self) -> &[u8; $n_bytes] {
177 &self.0
178 }
179
180 #[inline]
182 pub fn as_fixed_bytes_mut(&mut self) -> &mut [u8; $n_bytes] {
183 &mut self.0
184 }
185
186 #[inline]
188 pub const fn to_fixed_bytes(self) -> [u8; $n_bytes] {
189 self.0
190 }
191
192 #[inline]
194 pub fn as_ptr(&self) -> *const u8 {
195 self.as_bytes().as_ptr()
196 }
197
198 #[inline]
200 pub fn as_mut_ptr(&mut self) -> *mut u8 {
201 self.as_bytes_mut().as_mut_ptr()
202 }
203
204 pub fn assign_from_slice(&mut self, src: &[u8]) {
214 $crate::core_::assert_eq!(src.len(), $n_bytes);
215 self.as_bytes_mut().copy_from_slice(src);
216 }
217
218 pub fn from_slice(src: &[u8]) -> Self {
228 $crate::core_::assert_eq!(src.len(), $n_bytes);
229 let mut ret = Self::zero();
230 ret.assign_from_slice(src);
231 ret
232 }
233
234 #[inline]
236 pub fn covers(&self, b: &Self) -> bool {
237 &(b & self) == b
238 }
239
240 #[inline]
242 pub fn is_zero(&self) -> bool {
243 self.as_bytes().iter().all(|&byte| byte == 0u8)
244 }
245 }
246
247 impl $crate::core_::fmt::Debug for $name {
248 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
249 $crate::core_::write!(f, "{:#x}", self)
250 }
251 }
252
253 impl $crate::core_::fmt::Display for $name {
254 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
255 $crate::core_::write!(f, "0x")?;
256 for i in &self.0[0..2] {
257 $crate::core_::write!(f, "{:02x}", i)?;
258 }
259 $crate::core_::write!(f, "…")?;
260 for i in &self.0[$n_bytes - 2..$n_bytes] {
261 $crate::core_::write!(f, "{:02x}", i)?;
262 }
263 Ok(())
264 }
265 }
266
267 impl $crate::core_::fmt::LowerHex for $name {
268 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
269 if f.alternate() {
270 $crate::core_::write!(f, "0x")?;
271 }
272 for i in &self.0[..] {
273 $crate::core_::write!(f, "{:02x}", i)?;
274 }
275 Ok(())
276 }
277 }
278
279 impl $crate::core_::fmt::UpperHex for $name {
280 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
281 if f.alternate() {
282 $crate::core_::write!(f, "0X")?;
283 }
284 for i in &self.0[..] {
285 $crate::core_::write!(f, "{:02X}", i)?;
286 }
287 Ok(())
288 }
289 }
290
291 impl $crate::core_::marker::Copy for $name {}
292
293 #[cfg_attr(feature = "dev", allow(expl_impl_clone_on_copy))]
294 impl $crate::core_::clone::Clone for $name {
295 fn clone(&self) -> $name {
296 let mut ret = $name::zero();
297 ret.0.copy_from_slice(&self.0);
298 ret
299 }
300 }
301
302 impl $crate::core_::cmp::Eq for $name {}
303
304 impl $crate::core_::cmp::PartialOrd for $name {
305 fn partial_cmp(&self, other: &Self) -> Option<$crate::core_::cmp::Ordering> {
306 Some(self.cmp(other))
307 }
308 }
309
310 impl $crate::core_::hash::Hash for $name {
311 fn hash<H>(&self, state: &mut H) where H: $crate::core_::hash::Hasher {
312 state.write(&self.0);
313 }
314 }
315
316 impl<I> $crate::core_::ops::Index<I> for $name
317 where
318 I: $crate::core_::slice::SliceIndex<[u8]>
319 {
320 type Output = I::Output;
321
322 #[inline]
323 fn index(&self, index: I) -> &I::Output {
324 &self.as_bytes()[index]
325 }
326 }
327
328 impl<I> $crate::core_::ops::IndexMut<I> for $name
329 where
330 I: $crate::core_::slice::SliceIndex<[u8], Output = [u8]>
331 {
332 #[inline]
333 fn index_mut(&mut self, index: I) -> &mut I::Output {
334 &mut self.as_bytes_mut()[index]
335 }
336 }
337
338 impl $crate::core_::default::Default for $name {
339 #[inline]
340 fn default() -> Self {
341 Self::zero()
342 }
343 }
344
345 impl_ops_for_hash!($name, BitOr, bitor, BitOrAssign, bitor_assign, |, |=);
346 impl_ops_for_hash!($name, BitAnd, bitand, BitAndAssign, bitand_assign, &, &=);
347 impl_ops_for_hash!($name, BitXor, bitxor, BitXorAssign, bitxor_assign, ^, ^=);
348
349 impl_byteorder_for_fixed_hash!($name);
350 impl_rand_for_fixed_hash!($name);
351 impl_cmp_for_fixed_hash!($name);
352 impl_rustc_hex_for_fixed_hash!($name);
353 impl_quickcheck_for_fixed_hash!($name);
354 impl_arbitrary_for_fixed_hash!($name);
355 }
356}
357
358#[cfg(not(feature = "byteorder"))]
366#[macro_export]
367#[doc(hidden)]
368macro_rules! impl_byteorder_for_fixed_hash {
369 ( $name:ident ) => {};
370}
371
372#[cfg(feature = "byteorder")]
380#[macro_export]
381#[doc(hidden)]
382macro_rules! impl_byteorder_for_fixed_hash {
383 ( $name:ident ) => {
384 impl $name {
386 #[inline]
392 fn least_significant_bytes(&self, n: usize) -> &[u8] {
393 $crate::core_::assert_eq!(true, n <= Self::len_bytes());
394 &self[(Self::len_bytes() - n)..]
395 }
396
397 fn to_low_u64_with_byteorder<B>(&self) -> u64
398 where
399 B: $crate::byteorder::ByteOrder,
400 {
401 let mut buf = [0x0; 8];
402 let capped = $crate::core_::cmp::min(Self::len_bytes(), 8);
403 buf[(8 - capped)..].copy_from_slice(self.least_significant_bytes(capped));
404 B::read_u64(&buf)
405 }
406
407 #[inline]
414 pub fn to_low_u64_be(&self) -> u64 {
415 self.to_low_u64_with_byteorder::<$crate::byteorder::BigEndian>()
416 }
417
418 #[inline]
425 pub fn to_low_u64_le(&self) -> u64 {
426 self.to_low_u64_with_byteorder::<$crate::byteorder::LittleEndian>()
427 }
428
429 #[inline]
436 pub fn to_low_u64_ne(&self) -> u64 {
437 self.to_low_u64_with_byteorder::<$crate::byteorder::NativeEndian>()
438 }
439
440 fn from_low_u64_with_byteorder<B>(val: u64) -> Self
441 where
442 B: $crate::byteorder::ByteOrder,
443 {
444 let mut buf = [0x0; 8];
445 B::write_u64(&mut buf, val);
446 let capped = $crate::core_::cmp::min(Self::len_bytes(), 8);
447 let mut bytes = [0x0; $crate::core_::mem::size_of::<Self>()];
448 bytes[(Self::len_bytes() - capped)..].copy_from_slice(&buf[..capped]);
449 Self::from_slice(&bytes)
450 }
451
452 #[inline]
460 pub fn from_low_u64_be(val: u64) -> Self {
461 Self::from_low_u64_with_byteorder::<$crate::byteorder::BigEndian>(val)
462 }
463
464 #[inline]
472 pub fn from_low_u64_le(val: u64) -> Self {
473 Self::from_low_u64_with_byteorder::<$crate::byteorder::LittleEndian>(val)
474 }
475
476 #[inline]
484 pub fn from_low_u64_ne(val: u64) -> Self {
485 Self::from_low_u64_with_byteorder::<$crate::byteorder::NativeEndian>(val)
486 }
487 }
488 };
489}
490
491#[cfg(not(feature = "rand"))]
499#[macro_export]
500#[doc(hidden)]
501macro_rules! impl_rand_for_fixed_hash {
502 ( $name:ident ) => {};
503}
504
505#[cfg(feature = "rand")]
513#[macro_export]
514#[doc(hidden)]
515macro_rules! impl_rand_for_fixed_hash {
516 ( $name:ident ) => {
517 impl $crate::rand::distributions::Distribution<$name>
518 for $crate::rand::distributions::Standard
519 {
520 fn sample<R: $crate::rand::Rng + ?Sized>(&self, rng: &mut R) -> $name {
521 let mut ret = $name::zero();
522 for byte in ret.as_bytes_mut().iter_mut() {
523 *byte = rng.gen();
524 }
525 ret
526 }
527 }
528
529 impl $name {
531 pub fn randomize_using<R>(&mut self, rng: &mut R)
534 where
535 R: $crate::rand::Rng + ?Sized,
536 {
537 use $crate::rand::distributions::Distribution;
538 *self = $crate::rand::distributions::Standard.sample(rng);
539 }
540
541 pub fn randomize(&mut self) {
543 let mut rng = $crate::rand::rngs::OsRng;
544 self.randomize_using(&mut rng);
545 }
546
547 pub fn random_using<R>(rng: &mut R) -> Self
550 where
551 R: $crate::rand::Rng + ?Sized,
552 {
553 let mut ret = Self::zero();
554 ret.randomize_using(rng);
555 ret
556 }
557
558 pub fn random() -> Self {
560 let mut hash = Self::zero();
561 hash.randomize();
562 hash
563 }
564 }
565 };
566}
567
568#[macro_export]
569#[doc(hidden)]
570macro_rules! impl_cmp_for_fixed_hash {
571 ( $name:ident ) => {
572 impl $crate::core_::cmp::PartialEq for $name {
573 #[inline]
574 fn eq(&self, other: &Self) -> bool {
575 self.as_bytes() == other.as_bytes()
576 }
577 }
578
579 impl $crate::core_::cmp::Ord for $name {
580 #[inline]
581 fn cmp(&self, other: &Self) -> $crate::core_::cmp::Ordering {
582 self.as_bytes().cmp(other.as_bytes())
583 }
584 }
585 };
586}
587
588#[cfg(not(feature = "rustc-hex"))]
596#[macro_export]
597#[doc(hidden)]
598macro_rules! impl_rustc_hex_for_fixed_hash {
599 ( $name:ident ) => {};
600}
601
602#[cfg(feature = "rustc-hex")]
610#[macro_export]
611#[doc(hidden)]
612macro_rules! impl_rustc_hex_for_fixed_hash {
613 ( $name:ident ) => {
614 impl $crate::core_::str::FromStr for $name {
615 type Err = $crate::rustc_hex::FromHexError;
616
617 fn from_str(
628 input: &str,
629 ) -> $crate::core_::result::Result<$name, $crate::rustc_hex::FromHexError> {
630 let input = input.strip_prefix("0x").unwrap_or(input);
631 let mut iter = $crate::rustc_hex::FromHexIter::new(input);
632 let mut result = Self::zero();
633 for byte in result.as_mut() {
634 *byte = iter.next().ok_or(Self::Err::InvalidHexLength)??;
635 }
636 if iter.next().is_some() {
637 return Err(Self::Err::InvalidHexLength);
638 }
639 Ok(result)
640 }
641 }
642 };
643}
644
645#[cfg(not(feature = "quickcheck"))]
653#[macro_export]
654#[doc(hidden)]
655macro_rules! impl_quickcheck_for_fixed_hash {
656 ( $name:ident ) => {};
657}
658
659#[cfg(feature = "quickcheck")]
667#[macro_export]
668#[doc(hidden)]
669macro_rules! impl_quickcheck_for_fixed_hash {
670 ( $name:ident ) => {
671 impl $crate::quickcheck::Arbitrary for $name {
672 fn arbitrary(g: &mut $crate::quickcheck::Gen) -> Self {
673 let res: [u8; Self::len_bytes()] =
674 $crate::core_::array::from_fn(|_| u8::arbitrary(g));
675 Self::from(res)
676 }
677 }
678 };
679}
680
681#[cfg(not(feature = "arbitrary"))]
689#[macro_export]
690#[doc(hidden)]
691macro_rules! impl_arbitrary_for_fixed_hash {
692 ( $name:ident ) => {};
693}
694
695#[cfg(feature = "arbitrary")]
703#[macro_export]
704#[doc(hidden)]
705macro_rules! impl_arbitrary_for_fixed_hash {
706 ( $name:ident ) => {
707 impl $crate::arbitrary::Arbitrary<'_> for $name {
708 fn arbitrary(
709 u: &mut $crate::arbitrary::Unstructured<'_>,
710 ) -> $crate::arbitrary::Result<Self> {
711 let mut res = Self::zero();
712 u.fill_buffer(&mut res.0)?;
713 Ok(Self::from(res))
714 }
715 }
716 };
717}
718
719#[macro_export]
720#[doc(hidden)]
721macro_rules! impl_ops_for_hash {
722 (
723 $impl_for:ident,
724 $ops_trait_name:ident,
725 $ops_fn_name:ident,
726 $ops_assign_trait_name:ident,
727 $ops_assign_fn_name:ident,
728 $ops_tok:tt,
729 $ops_assign_tok:tt
730 ) => {
731 impl<'r> $crate::core_::ops::$ops_assign_trait_name<&'r $impl_for> for $impl_for {
732 fn $ops_assign_fn_name(&mut self, rhs: &'r $impl_for) {
733 for (lhs, rhs) in self.as_bytes_mut().iter_mut().zip(rhs.as_bytes()) {
734 *lhs $ops_assign_tok rhs;
735 }
736 }
737 }
738
739 impl $crate::core_::ops::$ops_assign_trait_name<$impl_for> for $impl_for {
740 #[inline]
741 fn $ops_assign_fn_name(&mut self, rhs: $impl_for) {
742 *self $ops_assign_tok &rhs;
743 }
744 }
745
746 impl<'l, 'r> $crate::core_::ops::$ops_trait_name<&'r $impl_for> for &'l $impl_for {
747 type Output = $impl_for;
748
749 fn $ops_fn_name(self, rhs: &'r $impl_for) -> Self::Output {
750 let mut ret = self.clone();
751 ret $ops_assign_tok rhs;
752 ret
753 }
754 }
755
756 impl $crate::core_::ops::$ops_trait_name<$impl_for> for $impl_for {
757 type Output = $impl_for;
758
759 #[inline]
760 fn $ops_fn_name(self, rhs: Self) -> Self::Output {
761 &self $ops_tok &rhs
762 }
763 }
764 };
765}
766
767#[macro_export(local_inner_macros)]
791macro_rules! impl_fixed_hash_conversions {
792 ($large_ty:ident, $small_ty:ident) => {
793 $crate::static_assertions::const_assert!(
794 $crate::core_::mem::size_of::<$small_ty>() < $crate::core_::mem::size_of::<$large_ty>()
795 );
796
797 impl From<$small_ty> for $large_ty {
798 fn from(value: $small_ty) -> $large_ty {
799 let large_ty_size = $large_ty::len_bytes();
800 let small_ty_size = $small_ty::len_bytes();
801
802 $crate::core_::debug_assert!(
803 large_ty_size > small_ty_size
804 && large_ty_size % 2 == 0
805 && small_ty_size % 2 == 0
806 );
807
808 let mut ret = $large_ty::zero();
809 ret.as_bytes_mut()[(large_ty_size - small_ty_size)..large_ty_size]
810 .copy_from_slice(value.as_bytes());
811 ret
812 }
813 }
814
815 impl From<$large_ty> for $small_ty {
816 fn from(value: $large_ty) -> $small_ty {
817 let large_ty_size = $large_ty::len_bytes();
818 let small_ty_size = $small_ty::len_bytes();
819
820 $crate::core_::debug_assert!(
821 large_ty_size > small_ty_size
822 && large_ty_size % 2 == 0
823 && small_ty_size % 2 == 0
824 );
825
826 let mut ret = $small_ty::zero();
827 ret.as_bytes_mut()
828 .copy_from_slice(&value[(large_ty_size - small_ty_size)..large_ty_size]);
829 ret
830 }
831 }
832 };
833}