use std::{
error::Error,
fmt::{self, Display},
};
use monoutils_store::ipld::cid::Cid;
use thiserror::Error;
use crate::filesystem::Utf8UnixPathSegment;
pub type FsResult<T> = Result<T, FsError>;
#[derive(Debug, Error)]
pub enum FsError {
#[error("Infallible error")]
Infallible(#[from] core::convert::Infallible),
#[error("Not a file: {0:?}")]
NotAFile(String),
#[error("Not a directory: {0:?}")]
NotADirectory(String),
#[error("Not a softlink: {0:?}")]
NotASoftLink(String),
#[error("Path not found: {0}")]
PathNotFound(String),
#[error("Custom error: {0}")]
Custom(#[from] AnyError),
#[error("IPLD Store error: {0}")]
IpldStore(#[from] monoutils_store::StoreError),
#[error("Invalid OpenFlag value: {0}")]
InvalidOpenFlag(u8),
#[error("Invalid EntityFlag value: {0}")]
InvalidEntityFlag(u8),
#[error("Invalid PathFlag value: {0}")]
InvalidPathFlag(u8),
#[error("Invalid path component: {0}")]
InvalidPathComponent(String),
#[error("Invalid search path: {0}")]
InvalidSearchPath(String),
#[error("SoftLink not supported yet: path: {0:?}")]
SoftLinkNotSupportedYet(Vec<Utf8UnixPathSegment>),
#[error("Invalid search path empty")]
InvalidSearchPathEmpty,
#[error("Unable to load entity: {0}")]
UnableToLoadEntity(Cid),
#[error("CID error: {0}")]
CidError(#[from] monoutils_store::ipld::cid::Error),
#[error("Path has root: {0}")]
PathHasRoot(String),
#[error("Source is not a directory: {0}")]
SourceIsNotADir(String),
#[error("Target is not a directory: {0}")]
TargetIsNotADir(String),
#[error("Path is empty")]
PathIsEmpty,
#[error("Maximum follow depth reached")]
MaxFollowDepthReached,
#[error("Broken softlink: {0}")]
BrokenSoftLink(Cid),
}
#[derive(Debug)]
pub struct AnyError {
error: anyhow::Error,
}
impl FsError {
pub fn custom(error: impl Into<anyhow::Error>) -> FsError {
FsError::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) -> FsResult<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 {}