use crate::chunk::ChunkAddress;
#[cfg(feature = "encryption")]
use crate::chunk::encryption::EncryptedChunkRef;
use super::error::FileError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EntryRef {
Plain(ChunkAddress),
#[cfg(feature = "encryption")]
Encrypted(EncryptedChunkRef),
}
impl EntryRef {
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, FileError> {
match bytes.len() {
32 => {
let addr_bytes: [u8; 32] = bytes.try_into().expect("length checked");
Ok(Self::Plain(ChunkAddress::from(addr_bytes)))
}
#[cfg(feature = "encryption")]
64 => {
let enc_ref = EncryptedChunkRef::try_from(bytes)
.map_err(|_| FileError::InvalidEntryRef { len: bytes.len() })?;
Ok(Self::Encrypted(enc_ref))
}
len => Err(FileError::InvalidEntryRef { len }),
}
}
pub const fn address(&self) -> &ChunkAddress {
match self {
Self::Plain(addr) => addr,
#[cfg(feature = "encryption")]
Self::Encrypted(enc) => enc.address(),
}
}
}
impl From<ChunkAddress> for EntryRef {
fn from(addr: ChunkAddress) -> Self {
Self::Plain(addr)
}
}
#[cfg(feature = "encryption")]
impl From<EncryptedChunkRef> for EntryRef {
fn from(enc: EncryptedChunkRef) -> Self {
Self::Encrypted(enc)
}
}
impl From<&EntryRef> for Vec<u8> {
fn from(entry_ref: &EntryRef) -> Self {
match entry_ref {
EntryRef::Plain(addr) => addr.as_bytes().to_vec(),
#[cfg(feature = "encryption")]
EntryRef::Encrypted(enc) => Self::from(enc),
}
}
}