use std::error::Error as StdError; use std::fmt; use std::io; use std::path::PathBuf; /// Error while trying to acquire a directory lock. #[derive(Debug, Fail)] pub enum LockError { /// Failed to acquired a lock as it is already held by another /// client. /// - In the context of a blocking lock, this means the lock was not released within some `timeout` period. /// - In the context of a non-blocking lock, this means the lock was busy at the moment of the call. #[fail( display = "Could not acquire lock as it is already held, possibly by a different process." )] LockBusy, /// Trying to acquire a lock failed with an `IOError` #[fail(display = "Failed to acquire the lock due to an io:Error.")] IOError(io::Error), } /// General IO error with an optional path to the offending file. #[derive(Debug)] pub struct IOError { path: Option, err: io::Error, } impl Into for IOError { fn into(self) -> io::Error { self.err } } impl fmt::Display for IOError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.path { Some(ref path) => write!(f, "io error occurred on path '{:?}': '{}'", path, self.err), None => write!(f, "io error occurred: '{}'", self.err), } } } impl StdError for IOError { fn description(&self) -> &str { "io error occurred" } fn cause(&self) -> Option<&StdError> { Some(&self.err) } } impl IOError { pub(crate) fn with_path(path: PathBuf, err: io::Error) -> Self { IOError { path: Some(path), err, } } } impl From for IOError { fn from(err: io::Error) -> IOError { IOError { path: None, err } } } /// Error that may occur when opening a directory #[derive(Debug)] pub enum OpenDirectoryError { /// The underlying directory does not exists. DoesNotExist(PathBuf), /// The path exists but is not a directory. NotADirectory(PathBuf), /// IoError IoError(io::Error), } impl From for OpenDirectoryError { fn from(io_err: io::Error) -> Self { OpenDirectoryError::IoError(io_err) } } impl fmt::Display for OpenDirectoryError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { OpenDirectoryError::DoesNotExist(ref path) => { write!(f, "the underlying directory '{:?}' does not exist", path) } OpenDirectoryError::NotADirectory(ref path) => { write!(f, "the path '{:?}' exists but is not a directory", path) } OpenDirectoryError::IoError(ref err) => write!( f, "IOError while trying to open/create the directory. {:?}", err ), } } } impl StdError for OpenDirectoryError { fn description(&self) -> &str { "error occurred while opening a directory" } fn cause(&self) -> Option<&StdError> { None } } /// Error that may occur when starting to write in a file #[derive(Debug)] pub enum OpenWriteError { /// Our directory is WORM, writing an existing file is forbidden. /// Checkout the `Directory` documentation. FileAlreadyExists(PathBuf), /// Any kind of IO error that happens when /// writing in the underlying IO device. IOError(IOError), } impl From for OpenWriteError { fn from(err: IOError) -> OpenWriteError { OpenWriteError::IOError(err) } } impl fmt::Display for OpenWriteError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { OpenWriteError::FileAlreadyExists(ref path) => { write!(f, "the file '{:?}' already exists", path) } OpenWriteError::IOError(ref err) => write!( f, "an io error occurred while opening a file for writing: '{}'", err ), } } } impl StdError for OpenWriteError { fn description(&self) -> &str { "error occurred while opening a file for writing" } fn cause(&self) -> Option<&StdError> { match *self { OpenWriteError::FileAlreadyExists(_) => None, OpenWriteError::IOError(ref err) => Some(err), } } } /// Error that may occur when accessing a file read #[derive(Debug)] pub enum OpenReadError { /// The file does not exists. FileDoesNotExist(PathBuf), /// Any kind of IO error that happens when /// interacting with the underlying IO device. IOError(IOError), } impl From for OpenReadError { fn from(err: IOError) -> OpenReadError { OpenReadError::IOError(err) } } impl fmt::Display for OpenReadError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { OpenReadError::FileDoesNotExist(ref path) => { write!(f, "the file '{:?}' does not exist", path) } OpenReadError::IOError(ref err) => write!( f, "an io error occurred while opening a file for reading: '{}'", err ), } } } impl StdError for OpenReadError { fn description(&self) -> &str { "error occurred while opening a file for reading" } fn cause(&self) -> Option<&StdError> { match *self { OpenReadError::FileDoesNotExist(_) => None, OpenReadError::IOError(ref err) => Some(err), } } } /// Error that may occur when trying to delete a file #[derive(Debug)] pub enum DeleteError { /// The file does not exists. FileDoesNotExist(PathBuf), /// Any kind of IO error that happens when /// interacting with the underlying IO device. IOError(IOError), } impl From for DeleteError { fn from(err: IOError) -> DeleteError { DeleteError::IOError(err) } } impl fmt::Display for DeleteError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { DeleteError::FileDoesNotExist(ref path) => { write!(f, "the file '{:?}' does not exist", path) } DeleteError::IOError(ref err) => { write!(f, "an io error occurred while deleting a file: '{}'", err) } } } } impl StdError for DeleteError { fn description(&self) -> &str { "error occurred while deleting a file" } fn cause(&self) -> Option<&StdError> { match *self { DeleteError::FileDoesNotExist(_) => None, DeleteError::IOError(ref err) => Some(err), } } }