#[cfg(feature = "serde")]
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
str::{self, FromStr},
};
use crate::{algorithm::HashAlgorithm, error::Error, hash::Hash};
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Id {
pub hash: Hash, }
impl Id {
pub fn new(hash: Hash) -> Self {
Self { hash }
}
}
impl Display for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.hash)
}
}
impl FromStr for Id {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(Self::new(Hash::from_hex_upper(HashAlgorithm::Sha256, s)?))
}
}
#[cfg(feature = "serde")]
impl Serialize for Id {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Id {
fn deserialize<De: Deserializer<'de>>(deserializer: De) -> Result<Self, De::Error> {
Self::from_str(&String::deserialize(deserializer)?)
.map_err(|e| De::Error::custom(format!("{}", e)))
}
}
pub trait ParseId {
fn parse_block_id(&self) -> Result<Id, Error>;
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE_SHA256_ID: &str =
"26C0A41F3243C6BCD7AD2DFF8A8D83A71D29D307B5326C227F734A1A512FE47D";
#[test]
fn parses_hex_strings() {
let id = Id::from_str(EXAMPLE_SHA256_ID).unwrap();
assert_eq!(
id.hash.as_slice(),
b"\x26\xC0\xA4\x1F\x32\x43\xC6\xBC\xD7\xAD\x2D\xFF\x8A\x8D\x83\xA7\
\x1D\x29\xD3\x07\xB5\x32\x6C\x22\x7F\x73\x4A\x1A\x51\x2F\xE4\x7D"
.as_ref()
);
}
#[test]
fn serializes_hex_strings() {
let id = Id::from_str(EXAMPLE_SHA256_ID).unwrap();
assert_eq!(&id.to_string(), EXAMPLE_SHA256_ID)
}
}