use std::io::{ErrorKind as IoErrorKind, Error as IoError}; use crate::*; #[derive(Debug, PartialEq)] pub enum EntryErrorKind { NotFound, PermissionDenied, } pub struct EntryReadError { pub path: PathBuf, pub error_kind: EntryErrorKind, } pub struct EntryWriteError { pub path: PathBuf, pub error_kind: EntryErrorKind, } impl From for EntryWriteError { fn from(error: EntryReadError) -> Self { EntryWriteError { path: error.path, error_kind: error.error_kind } } } pub(crate) fn io_result_to_read_result(io_result: Result, path: &Path) -> ReadResult { match io_result { Ok(t) => Ok(t), Err(io_error) => { match io_error_to_entry_error(io_error) { Ok(error_kind) => Err( EntryReadError { path: path.to_path_buf(), error_kind }), Err(err) => panic!("Unexpected IO error while attempting to read from {path:?}: {err:?}"), } } } } pub(crate) fn io_result_to_write_result(io_result: Result, path: &Path) -> WriteResult { match io_result { Ok(t) => Ok(t), Err(io_error) => { match io_error_to_entry_error(io_error) { Ok(error_kind) => Err( EntryWriteError { path: path.to_path_buf(), error_kind }), Err(err) => panic!("Unexpected IO error while attempting to write to {path:?}: {err:?}"), } } } } fn io_error_to_entry_error(io_error: IoError) -> Result { match io_error.kind() { IoErrorKind::NotFound => Ok(EntryErrorKind::NotFound), // An intermediate path component was a plain file, not a directory IoErrorKind::NotADirectory => Ok(EntryErrorKind::NotFound), // A cyclic symbolic link chain was included in the provided path IoErrorKind::FilesystemLoop => Ok(EntryErrorKind::NotFound), IoErrorKind::PermissionDenied => Ok(EntryErrorKind::PermissionDenied), err => Err(err), } } impl std::fmt::Debug for EntryReadError { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { write!(f, "Error while attempting to read from file '{:?}': {:?}", self.path, self.error_kind) } } impl std::fmt::Debug for EntryWriteError { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { write!(f, "Error while attempting to write to file '{:?}': {:?}", self.path, self.error_kind) } }