macro_rules! impl_primitive {
(@new $ty:ty) => {
impl $ty {
#[doc = concat!("Creates a new `", stringify!($ty), "` from a 32-byte array.")]
pub const fn new(array: [u8; 32]) -> Self {
Self(array)
}
}
};
(@zero $ty:ty) => {
impl $ty {
#[doc = concat!("Creates a new zero `", stringify!($ty), "`.")]
pub const fn zero() -> Self {
Self([0; 32])
}
#[doc = concat!("Checks whether `", stringify!($ty), "` is zero.")]
pub fn is_zero(&self) -> bool {
self == &Self::zero()
}
}
};
(@into_bytes $ty:ty) => {
impl $ty {
#[doc = concat!("Returns `", stringify!($ty), "`as bytes array.")]
pub fn into_bytes(self) -> [u8; 32] {
self.0
}
}
};
(@from_u64 $ty:ty) => {
impl From<u64> for $ty {
fn from(value: u64) -> Self {
let mut id = Self::zero();
id.0[..8].copy_from_slice(&value.to_le_bytes()[..]);
id
}
}
};
(@from_h256 $ty:ty) => {
impl From<H256> for $ty {
fn from(h256: H256) -> Self {
Self::new(h256.to_fixed_bytes())
}
}
};
(@into_h256 $ty:ty) => {
impl From<$ty> for H256 {
fn from(value: $ty) -> Self {
Self(value.0)
}
}
};
(@from_str $ty:ty) => {
impl FromStr for $ty {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.strip_prefix("0x") {
Some(s) if s.len() == 64 => {
let mut id = Self::zero();
hex::decode_to_slice(s, &mut id.0)
.map_err(|_| ConversionError::InvalidHexString)?;
Ok(id)
}
_ => Err(ConversionError::InvalidHexString),
}
}
}
};
(@try_from_slice $ty:ty) => {
impl TryFrom<&[u8]> for $ty {
type Error = ConversionError;
fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
if slice.len() != 32 {
return Err(ConversionError::InvalidSliceLength);
}
let mut ret = Self([0; 32]);
ret.as_mut().copy_from_slice(slice);
Ok(ret)
}
}
};
(@display $ty:ty) => {
impl fmt::Display for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let byte_array = utils::ByteSliceFormatter::Array(&self.0);
let is_alternate = f.alternate();
if is_alternate {
f.write_str(concat!(stringify!($ty), "("))?;
}
byte_array.fmt(f)?;
if is_alternate {
f.write_str(")")?;
}
Ok(())
}
}
};
(@debug $ty:ty) => {
impl fmt::Debug for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
};
(@serde $ty:ty) => {
#[cfg(feature = "serde")]
impl Serialize for $ty {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(self)
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(utils::HexStrVisitor::new())
}
}
};
($($feature:ident)*, $ty:ty) => {
$(
macros::impl_primitive!(@$feature $ty);
)*
};
}
pub(crate) use impl_primitive;