1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
use crate::encoding::{deserialize_from_str, hex_formatter}; use crate::{expect_len, to_hex}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::convert::TryFrom; use std::str::FromStr; #[derive(Clone, PartialEq, Eq, Hash)] pub struct BlockHash([u8; BlockHash::LEN]); impl BlockHash { pub const LEN: usize = 32; pub fn zero() -> Self { Self([0u8; BlockHash::LEN]) } pub fn as_bytes(&self) -> &[u8] { &self.0 } } impl FromStr for BlockHash { type Err = anyhow::Error; fn from_str(s: &str) -> Result<Self, Self::Err> { BlockHash::try_from(hex::decode(s.as_bytes())?.as_slice()) } } impl TryFrom<&[u8]> for BlockHash { type Error = anyhow::Error; fn try_from(value: &[u8]) -> Result<Self, Self::Error> { expect_len(value.len(), Self::LEN, "Block hash")?; let mut bh = BlockHash([0u8; Self::LEN]); bh.0.copy_from_slice(&value); Ok(bh) } } impl std::fmt::Display for BlockHash { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:X}", &self) } } impl std::fmt::Debug for BlockHash { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "BlockHash(")?; hex_formatter(f, &self.0)?; write!(f, ")")?; Ok(()) } } impl std::fmt::UpperHex for BlockHash { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { hex_formatter(f, &self.0.as_ref()) } } impl Serialize for BlockHash { fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where S: Serializer, { serializer.serialize_str(to_hex(&self.0).as_str()) } } impl<'de> Deserialize<'de> for BlockHash { fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where D: Deserializer<'de>, { deserialize_from_str(deserializer) } }