use std::{fmt::Display, str::FromStr}; use serde::{Deserialize, Serialize}; use crate::signature::PublicKey; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Address { value: [u8; 32], } impl Address { pub fn new(value: [u8; 32]) -> Self { Self { value } } pub fn value(&self) -> &[u8; 32] { &self.value } } impl AsRef<[u8]> for Address { fn as_ref(&self) -> &[u8] { &self.value } } impl From<&PublicKey> for Address { fn from(value: &PublicKey) -> Self { // TODO: Check specs Self::new(*value.value()) } } #[derive(Debug, thiserror::Error)] pub enum AddressError { #[error("invalid hex")] InvalidHex(#[from] hex::FromHexError), #[error("invalid length: expected 32 bytes, got {0}")] InvalidLength(usize), } impl FromStr for Address { type Err = AddressError; fn from_str(s: &str) -> Result { let bytes = hex::decode(s)?; if bytes.len() != 32 { return Err(AddressError::InvalidLength(bytes.len())); } let mut value = [0u8; 32]; value.copy_from_slice(&bytes); Ok(Address { value }) } } impl Display for Address { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", hex::encode(self.value)) } } impl Serialize for Address { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let hex_string = self.to_string(); hex_string.serialize(serializer) } } impl<'de> Deserialize<'de> for Address { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let hex_string = String::deserialize(deserializer)?; Address::from_str(&hex_string).map_err(serde::de::Error::custom) } } #[cfg(test)] mod tests { use crate::{Address, address::AddressError}; #[test] fn parse_valid_address() { let hex_str = "00".repeat(32); // 64 hex chars = 32 bytes let addr: Address = hex_str.parse().unwrap(); assert_eq!(addr.value, [0u8; 32]); } #[test] fn parse_invalid_hex() { let hex_str = "zz".repeat(32); // invalid hex chars let result = hex_str.parse::
().unwrap_err(); assert!(matches!(result, AddressError::InvalidHex(_))); } #[test] fn parse_wrong_length_short() { let hex_str = "00".repeat(31); // 62 chars = 31 bytes let result = hex_str.parse::
().unwrap_err(); assert!(matches!(result, AddressError::InvalidLength(_))); } #[test] fn parse_wrong_length_long() { let hex_str = "00".repeat(33); // 66 chars = 33 bytes let result = hex_str.parse::
().unwrap_err(); assert!(matches!(result, AddressError::InvalidLength(_))); } }