use std::fmt; use data_encoding::HEXLOWER_PERMISSIVE; use crate::IdError; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FileId(pub [u8; 20]); impl FileId { pub fn from_raw(src: &[u8]) -> Result { let mut dst = [0u8; 20]; if src.len() != 20 { return Err(IdError::InvalidId); } dst.clone_from_slice(src); Ok(FileId(dst)) } pub fn from_base16(src: &str) -> Result { let mut dst = [0u8; 20]; HEXLOWER_PERMISSIVE .decode_mut(src.as_bytes(), &mut dst) .map_err(|_| IdError::InvalidId)?; Ok(FileId(dst)) } pub fn base16(&self) -> String { HEXLOWER_PERMISSIVE.encode(&self.0) } } impl fmt::Debug for FileId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("FileId").field(&self.base16()).finish() } } impl fmt::Display for FileId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.base16()) } } impl TryFrom<&[u8]> for FileId { type Error = IdError; fn try_from(value: &[u8]) -> Result { Self::from_raw(value) } }