near-crypto-v01 0.1.0

This is an internal crate for common cryptographic types.
Documentation
macro_rules! to_str {
    ($v:expr) => {
        ::std::convert::identity::<String>($v.into()).as_str()
    };
}

macro_rules! common_conversions {
    ($ty:ty, $what:literal) => {
        impl ::std::convert::TryFrom<String> for $ty {
            type Error = ();

            fn try_from(value: String) -> Result<Self, ()> {
                Self::try_from(value.as_str())
            }
        }

        impl Into<String> for $ty {
            fn into(self) -> String {
                bs58::encode(self).into_string()
            }
        }

        impl Into<String> for &$ty {
            fn into(self) -> String {
                bs58::encode(self).into_string()
            }
        }

        impl ::std::fmt::Debug for $ty {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str(to_str!(self))
            }
        }

        impl ::std::fmt::Display for $ty {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str(to_str!(self))
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $ty {
            fn deserialize<D: ::serde::Deserializer<'de>>(
                deserializer: D,
            ) -> Result<Self, D::Error> {
                let s = <&str as ::serde::Deserialize<'de>>::deserialize(deserializer)?;
                <Self as ::std::convert::TryFrom<&str>>::try_from(s).map_err(|_| {
                    <D::Error as ::serde::de::Error>::invalid_value(
                        ::serde::de::Unexpected::Str(s),
                        &concat!("a valid ", $what),
                    )
                })
            }
        }

        impl ::serde::Serialize for $ty {
            fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
                serializer.serialize_str(to_str!(self))
            }
        }
    };
}

macro_rules! common_conversions_fixed {
    ($ty:ty, $l:literal, $bytes:expr, $what:literal) => {
        impl ::std::convert::TryFrom<&[u8]> for $ty {
            type Error = ();

            fn try_from(value: &[u8]) -> Result<Self, ()> {
                match value.len() {
                    $l => Self::try_from(::arrayref::array_ref!(value, 0, $l)).or(Err(())),
                    _ => Err(()),
                }
            }
        }

        impl AsRef<[u8; $l]> for $ty {
            fn as_ref(&self) -> &[u8; $l] {
                ::std::convert::identity::<fn(&$ty) -> &[u8; $l]>($bytes)(self)
            }
        }

        impl AsRef<[u8]> for $ty {
            fn as_ref(&self) -> &[u8] {
                <Self as AsRef<[u8; $l]>>::as_ref(self)
            }
        }

        impl Into<[u8; $l]> for $ty {
            fn into(self) -> [u8; $l] {
                *self.as_ref()
            }
        }

        impl Into<[u8; $l]> for &$ty {
            fn into(self) -> [u8; $l] {
                *self.as_ref()
            }
        }

        impl ::std::convert::TryFrom<&str> for $ty {
            type Error = ();

            fn try_from(value: &str) -> Result<Self, ()> {
                let mut buf = [0; $l];
                match bs58::decode(value).into(&mut buf[..]) {
                    Ok($l) => Self::try_from(&buf).or(Err(())),
                    _ => Err(()),
                }
            }
        }

        common_conversions!($ty, $what);
    };
}

macro_rules! eq {
    ($ty:ty, $e:expr) => {
        impl PartialEq for $ty {
            fn eq(&self, other: &Self) -> bool {
                ::std::convert::identity::<fn(&Self, &Self) -> bool>($e)(self, other)
            }
        }

        impl Eq for $ty {}
    };
}

macro_rules! value_type {
    ($vis:vis, $ty:ident, $l:literal, $what:literal) => {
        #[derive(Copy, Clone)]
        $vis struct $ty(pub [u8; $l]);

        eq!($ty, |a, b| a.0[..] == b.0[..]);

        impl AsMut<[u8; $l]> for $ty {
            fn as_mut(&mut self) -> &mut [u8; $l] {
                &mut self.0
            }
        }

        impl AsMut<[u8]> for $ty {
            fn as_mut(&mut self) -> &mut [u8] {
                &mut self.0[..]
            }
        }

        impl From<&[u8; $l]> for $ty {
            fn from(value: &[u8; $l]) -> Self {
                Self(*value)
            }
        }

        impl borsh::BorshSerialize for $ty {
            #[inline]
            fn serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
                writer.write_all(&self.0)
            }
        }

        impl borsh::BorshDeserialize for $ty {
            #[inline]
            fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
                if buf.len() < $l {
                    return Err(std::io::Error::new(
                        std::io::ErrorKind::InvalidInput,
                        "Unexpected length of input",
                    ));
                }

                let mut data = [0u8; $l];
                data.copy_from_slice(&buf[..$l]);
                *buf = &buf[$l..];
                Ok($ty(data))
            }
        }

        common_conversions_fixed!($ty, $l, |s| &s.0, $what);
    };
}