use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CoreError {
Syscall {
code: i32,
op: &'static str,
},
}
impl CoreError {
pub fn sys(code: i32, op: &'static str) -> Self {
Self::Syscall { code, op }
}
pub fn raw_os_error(&self) -> Option<i32> {
match self {
Self::Syscall { code, .. } => Some(*code),
}
}
pub fn to_io_error(&self) -> std::io::Error {
std::io::Error::from_raw_os_error(self.raw_os_error().unwrap_or(libc::EIO))
}
}
impl fmt::Display for CoreError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Syscall { code, op } => write!(f, "{op} failed (code={code})"),
}
}
}
impl std::error::Error for CoreError {}
#[inline(always)]
pub(crate) fn syscall_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
if ret == -1 {
let code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
Err(CoreError::sys(code, op))
} else {
Ok(())
}
}
#[inline(always)]
pub(crate) fn posix_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
if ret != 0 {
Err(CoreError::sys(ret, op))
} else {
Ok(())
}
}