macro_rules! arr_newtype_fmt_impl {
($ty:ident, $bytes:expr $(, $gen:ident: $gent:ident)*) => {
impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> {
#[inline]
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
#[allow(unused)]
use crate::Hash as _;
let case = $crate::hex::Case::Lower;
if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
$crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
} else {
$crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
}
}
}
impl<$($gen: $gent),*> $crate::_export::_core::fmt::UpperHex for $ty<$($gen),*> {
#[inline]
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
#[allow(unused)]
use crate::Hash as _;
let case = $crate::hex::Case::Upper;
if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
$crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
} else {
$crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
}
}
}
impl<$($gen: $gent),*> $crate::_export::_core::fmt::Display for $ty<$($gen),*> {
#[inline]
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
$crate::_export::_core::fmt::LowerHex::fmt(self, f)
}
}
impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> {
#[inline]
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
write!(f, "{:#}", self)
}
}
}
}
pub(crate) use arr_newtype_fmt_impl;
macro_rules! hash_trait_impls {
($bits:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
impl<$($gen: $gent),*> Hash<$($gen),*> {
pub fn forward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
$crate::hex::DisplayHex::as_hex(&self.0)
}
pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
$crate::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev())
}
pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self {
unsafe { &*(bytes as *const _ as *const Self) }
}
pub fn from_bytes_mut(bytes: &mut [u8; $bits / 8]) -> &mut Self {
unsafe { &mut *(bytes as *mut _ as *mut Self) }
}
}
impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> {
type Err = $crate::hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use $crate::hex::{FromHex, HexToBytesIter};
use $crate::Hash;
let inner: [u8; $bits / 8] = if $reverse {
FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
} else {
FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
};
Ok(Self::from_byte_array(inner))
}
}
$crate::internal_macros::arr_newtype_fmt_impl!(Hash, $bits / 8 $(, $gen: $gent)*);
serde_impl!(Hash, $bits / 8 $(, $gen: $gent)*);
borrow_slice_impl!(Hash $(, $gen: $gent)*);
impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8; $bits / 8]> for Hash<$($gen),*> {
fn as_ref(&self) -> &[u8; $bits / 8] {
&self.0
}
}
impl<I: SliceIndex<[u8]> $(, $gen: $gent)*> Index<I> for Hash<$($gen),*> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}
impl<$($gen: $gent),*> crate::Hash for Hash<$($gen),*> {
type Engine = HashEngine;
type Bytes = [u8; $bits / 8];
const LEN: usize = $bits / 8;
const DISPLAY_BACKWARD: bool = $reverse;
fn engine() -> Self::Engine {
Self::internal_engine()
}
fn from_engine(e: HashEngine) -> Hash<$($gen),*> {
from_engine(e)
}
fn from_slice(sl: &[u8]) -> Result<Hash<$($gen),*>, FromSliceError> {
if sl.len() != $bits / 8 {
Err(FromSliceError{expected: Self::LEN, got: sl.len()})
} else {
let mut ret = [0; $bits / 8];
ret.copy_from_slice(sl);
Ok(Self::internal_new(ret))
}
}
fn to_byte_array(self) -> Self::Bytes {
self.0
}
fn as_byte_array(&self) -> &Self::Bytes {
&self.0
}
fn from_byte_array(bytes: Self::Bytes) -> Self {
Self::internal_new(bytes)
}
fn all_zeros() -> Self {
Hash::internal_new([0x00; $bits / 8])
}
}
}
}
pub(crate) use hash_trait_impls;
macro_rules! hash_type {
($bits:expr, $reverse:expr, $doc:literal, $schemars:literal) => {
#[doc = $doc]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "schemars", derive(crate::schemars::JsonSchema))]
#[repr(transparent)]
pub struct Hash(
#[cfg_attr(feature = "schemars", schemars(schema_with = $schemars))] [u8; $bits / 8],
);
impl Hash {
fn internal_new(arr: [u8; $bits / 8]) -> Self { Hash(arr) }
fn internal_engine() -> HashEngine { Default::default() }
}
crate::internal_macros::hash_trait_impls!($bits, $reverse);
};
}
pub(crate) use hash_type;