use std::{
error::Error,
fmt::{self, Display},
};
use libipld::Cid;
use thiserror::Error;
use super::Codec;
pub type StoreResult<T> = Result<T, StoreError>;
#[derive(Debug, Error, PartialEq)]
pub enum StoreError {
#[error("Block not found: {0}")]
BlockNotFound(Cid),
#[error("Node block too large: {0} > {1}")]
NodeBlockTooLarge(u64, u64),
#[error("Raw block too large: {0} > {1}")]
RawBlockTooLarge(u64, u64),
#[error("Unsupported Codec: {0}")]
UnsupportedCodec(u64),
#[error("Unexpected block codec: expected: {0:?} got: {1:?}")]
UnexpectedBlockCodec(Codec, Codec),
#[error("Custom error: {0}")]
Custom(#[from] AnyError),
#[error("Layout error: {0}")]
LayoutError(#[from] LayoutError),
}
#[derive(Debug, Error, PartialEq)]
pub enum LayoutError {
#[error("No leaf block found")]
NoLeafBlock,
}
#[derive(Debug)]
pub struct AnyError {
error: anyhow::Error,
}
impl StoreError {
pub fn custom(error: impl Into<anyhow::Error>) -> StoreError {
StoreError::Custom(AnyError {
error: error.into(),
})
}
}
impl AnyError {
pub fn downcast<T>(&self) -> Option<&T>
where
T: Display + fmt::Debug + Send + Sync + 'static,
{
self.error.downcast_ref::<T>()
}
}
#[allow(non_snake_case)]
pub fn Ok<T>(value: T) -> StoreResult<T> {
Result::Ok(value)
}
impl PartialEq for AnyError {
fn eq(&self, other: &Self) -> bool {
self.error.to_string() == other.error.to_string()
}
}
impl Display for AnyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.error)
}
}
impl Error for AnyError {}