use nuts_backend::Backend;
use thiserror::Error;
use crate::header::HeaderMagicError;
#[derive(Debug, Error)]
pub enum Error<B: Backend> {
#[error(transparent)]
Bytes(nuts_bytes::Error),
#[error(transparent)]
Container(#[from] nuts_container::Error<B>),
#[error("unsupported revision: {0}, latest supported version is {1}")]
UnsupportedRevision(u16, String),
#[error("no top-id available")]
NoTopId,
#[error("could not parse the header of the archive")]
InvalidHeader(nuts_bytes::Error),
#[error("the archive is full")]
Full,
#[error("the block size is too small")]
InvalidBlockSize,
#[error("not an archive node: {0}")]
InvalidNode(B::Id),
#[error("could not fill the whole buffer")]
UnexpectedEof,
#[error("could not detect the type of the entry {}", if let Some(id) = .0 { format!("stored in {}", id) } else { "in unknown block".to_string() })]
InvalidType(Option<B::Id>),
}
impl<B: Backend> From<nuts_bytes::Error> for Error<B> {
fn from(cause: nuts_bytes::Error) -> Self {
match &cause {
nuts_bytes::Error::Custom(cust) => {
if cust.is::<HeaderMagicError>() {
Error::InvalidHeader(cause)
} else {
Error::Bytes(cause)
}
}
nuts_bytes::Error::TakeBytes(nuts_bytes::TakeBytesError::Eof)
| nuts_bytes::Error::PutBytes(nuts_bytes::PutBytesError::NoSpace) => {
Error::InvalidBlockSize
}
_ => Error::Bytes(cause),
}
}
}
pub type ArchiveResult<T, B> = Result<T, Error<B>>;