51 lines
1.2 KiB
Rust
51 lines
1.2 KiB
Rust
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<FileId, IdError> {
|
|
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<FileId, IdError> {
|
|
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, Self::Error> {
|
|
Self::from_raw(value)
|
|
}
|
|
}
|