use core::convert::TryFrom;
use core::fmt::{self, Display, Formatter};
use core::str::FromStr;
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct PublicKey {
key_as_bytes: [u8; 32],
}
impl PublicKey {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.key_as_bytes
}
}
impl From<[u8; 32]> for PublicKey {
fn from(bytes: [u8; 32]) -> Self {
PublicKey {
key_as_bytes: bytes,
}
}
}
impl From<&[u8; 32]> for PublicKey {
fn from(bytes: &[u8; 32]) -> Self {
PublicKey {
key_as_bytes: *bytes,
}
}
}
impl TryFrom<&[u8]> for PublicKey {
type Error = PublicKeyParseError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
Ok(<&[u8; 32]>::try_from(bytes)
.map_err(|_| PublicKeyParseError {})?
.into())
}
}
impl TryFrom<Vec<u8>> for PublicKey {
type Error = PublicKeyParseError;
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
if value.len() != 32 {
return Err(PublicKeyParseError {});
}
PublicKey::try_from(&value[..])
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct PublicKeyParseError;
impl FromStr for PublicKey {
type Err = PublicKeyParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let point_bytes = bs58::decode(s)
.into_vec()
.map_err(|_| PublicKeyParseError)?;
PublicKey::try_from(point_bytes.as_slice()).map_err(|_| PublicKeyParseError)
}
}
impl Display for PublicKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let serialized_b58 = bs58::encode(self.key_as_bytes).into_string();
write!(f, "{}", serialized_b58)
}
}
impl Display for PublicKeyParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}