use std::{
io,
path::{Path, PathBuf},
};
use thiserror::Error;
use crate::DirEntry;
#[derive(Debug, Error)]
pub enum ErrorKind {
#[error("{0}")]
Io(#[source] io::Error),
#[error("symlink loop detected")]
LoopDetected,
}
#[derive(Debug, Error)]
#[error("Error on {path} with depth {depth} and kind: {kind}")]
pub struct Error {
path: PathBuf,
depth: usize,
kind: ErrorKind,
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
impl Error {
#[inline]
pub fn path(&self) -> &Path {
&self.path
}
#[inline]
pub fn depth(&self) -> usize {
self.depth
}
#[inline]
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
#[inline]
pub fn is_io(&self) -> bool {
matches!(self.kind, ErrorKind::Io(_))
}
#[inline]
pub fn is_loop(&self) -> bool {
matches!(self.kind, ErrorKind::LoopDetected)
}
#[inline]
pub fn io_error(&self) -> Option<&io::Error> {
match &self.kind {
ErrorKind::Io(e) => Some(e),
ErrorKind::LoopDetected => None,
}
}
#[inline]
pub fn into_io_error(self) -> Option<io::Error> {
match self.kind {
ErrorKind::Io(err) => Some(err),
ErrorKind::LoopDetected => None,
}
}
pub(crate) fn from_entry<T>(entry: &DirEntry<T>, source: io::Error) -> Self {
Self {
path: entry.path().to_path_buf(),
depth: entry.depth(),
kind: ErrorKind::Io(source),
}
}
pub(crate) fn new_io_error(path: PathBuf, depth: usize, source: io::Error) -> Self {
Self {
path,
depth,
kind: ErrorKind::Io(source),
}
}
pub(crate) fn loop_detected(path: PathBuf, depth: usize) -> Self {
Self {
path,
depth,
kind: ErrorKind::LoopDetected,
}
}
}