#[cfg(doc)]
use crate::{Hash, Resolve};
#[macro_export]
macro_rules! error_parse {
($($t:tt)*) => {
$crate::Error::Parse($crate::anyhow!($($t)*))
};
}
#[macro_export]
macro_rules! error_fetch {
($($t:tt)*) => {
$crate::Error::Fetch($crate::anyhow!($($t)*))
};
}
#[macro_export]
macro_rules! error_operation {
($($t:tt)*) => {
$crate::Error::Operation($crate::anyhow!($($t)*))
};
}
#[macro_export]
macro_rules! error_consistency {
($($t:tt)*) => {
$crate::Error::Consistency($crate::anyhow!($($t)*))
};
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error(transparent)]
Parse(anyhow::Error),
#[error(transparent)]
Fetch(anyhow::Error),
#[error(transparent)]
Operation(anyhow::Error),
#[error(transparent)]
Consistency(anyhow::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("extra input left")]
ExtraInputLeft,
#[error("end of input")]
EndOfInput,
#[error("address index out of bounds")]
AddressOutOfBounds,
#[error("hash resolution mismatch")]
ResolutionMismatch,
#[error("full hash mismatch")]
FullHashMismatch,
#[error("discriminant overflow")]
DiscriminantOverflow,
#[error("zero")]
Zero,
#[error("out of bounds")]
OutOfBounds,
#[error("length out of bounds")]
UnsupportedLength,
#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),
#[error("not implemented")]
Unimplemented,
#[error("hash not found in the resolve")]
HashNotFound,
#[error("interrupted")]
Interrupted,
}
impl Error {
pub fn parse(e: impl Into<anyhow::Error>) -> Self {
Self::Parse(e.into())
}
pub fn fetch(e: impl Into<anyhow::Error>) -> Self {
Self::Fetch(e.into())
}
pub fn operation(e: impl Into<anyhow::Error>) -> Self {
Self::Operation(e.into())
}
pub fn consistency(e: impl Into<anyhow::Error>) -> Self {
Self::Consistency(e.into())
}
pub fn io(e: impl Into<std::io::Error>) -> Self {
e.into().into()
}
fn io_kind(&self) -> std::io::ErrorKind {
use std::io::ErrorKind;
match self {
Error::Parse(_) => ErrorKind::InvalidData,
Error::Fetch(_) => ErrorKind::Other,
Error::Operation(_) => ErrorKind::Other,
Error::Consistency(_) => ErrorKind::InvalidData,
Error::Io(e) => e.kind(),
Error::ExtraInputLeft => ErrorKind::InvalidData,
Error::EndOfInput => ErrorKind::UnexpectedEof,
Error::AddressOutOfBounds => ErrorKind::Other,
Error::ResolutionMismatch => ErrorKind::InvalidData,
Error::FullHashMismatch => ErrorKind::InvalidData,
Error::DiscriminantOverflow => ErrorKind::InvalidData,
Error::Zero => ErrorKind::InvalidData,
Error::OutOfBounds => ErrorKind::InvalidData,
Error::UnsupportedLength => ErrorKind::FileTooLarge,
Error::Utf8(_) => ErrorKind::InvalidData,
Error::Unimplemented => ErrorKind::Unsupported,
Error::HashNotFound => ErrorKind::NotFound,
Error::Interrupted => ErrorKind::Interrupted,
}
}
}
impl From<Error> for std::io::Error {
fn from(value: Error) -> Self {
match value {
Error::Io(e) => e,
e => Self::new(e.io_kind(), e),
}
}
}
pub type Result<T> = std::result::Result<T, Error>;