use std::fmt;
use std::io;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorOperation {
Open,
Lock,
Unlock,
Close,
}
impl fmt::Display for ErrorOperation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Open => "open lock file",
Self::Lock => "acquire file lock",
Self::Unlock => "release file lock",
Self::Close => "close lock file",
})
}
}
#[derive(Debug)]
pub struct Error {
operation: ErrorOperation,
source: io::Error,
}
impl Error {
pub(crate) fn new(operation: ErrorOperation, source: io::Error) -> Self {
Self { operation, source }
}
pub fn operation(&self) -> ErrorOperation {
self.operation
}
pub fn kind(&self) -> io::ErrorKind {
self.source.kind()
}
pub fn raw_os_error(&self) -> Option<i32> {
self.source.raw_os_error()
}
pub fn io_error(&self) -> &io::Error {
&self.source
}
pub fn into_io_error(self) -> io::Error {
self.source
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "failed to {}: {}", self.operation, self.source)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
pub type Result<T> = std::result::Result<T, Error>;