use std::error::Error;
use std::fmt::{
Display,
Formatter,
Result as FmtResult,
};
use crate::{
FsErrorKind,
FsOperation,
FsPath,
};
#[derive(Debug)]
pub struct FsError {
pub kind: FsErrorKind,
pub operation: FsOperation,
pub path: Option<Box<FsPath>>,
pub target: Option<Box<FsPath>>,
pub provider: Option<Box<str>>,
pub message: Box<str>,
pub source: Option<Box<dyn Error + Send + Sync + 'static>>,
}
impl FsError {
#[inline]
pub fn new(kind: FsErrorKind, operation: FsOperation, message: &str) -> Self {
Self {
kind,
operation,
path: None,
target: None,
provider: None,
message: message.into(),
source: None,
}
}
#[inline]
pub fn with_source<E>(kind: FsErrorKind, operation: FsOperation, message: &str, source: E) -> Self
where
E: Error + Send + Sync + 'static,
{
Self {
source: Some(Box::new(source)),
..Self::new(kind, operation, message)
}
}
#[inline]
#[must_use]
pub fn with_path(mut self, path: FsPath) -> Self {
self.path = Some(Box::new(path));
self
}
#[inline]
#[must_use]
pub fn with_target(mut self, target: FsPath) -> Self {
self.target = Some(Box::new(target));
self
}
#[inline]
#[must_use]
pub fn with_provider(mut self, provider: &str) -> Self {
self.provider = Some(provider.into());
self
}
#[inline]
pub fn invalid_path(operation: FsOperation, message: &str) -> Self {
Self::new(FsErrorKind::InvalidPath, operation, message)
}
#[inline]
#[must_use]
pub fn kind(&self) -> FsErrorKind {
self.kind
}
}
impl Display for FsError {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
write!(
formatter,
"{:?} failed with {:?}: {}",
self.operation, self.kind, self.message,
)
}
}
impl Error for FsError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source.as_deref().map(|source| source as &(dyn Error + 'static))
}
}