use std::ffi::CString;
use std::fmt;
use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PrimitiveError {
pub operation: &'static str,
pub path: PathBuf,
pub errno: i32,
}
impl PrimitiveError {
pub fn last_os_error(operation: &'static str, path: &Path) -> PrimitiveError {
let errno: i32 = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
return PrimitiveError { operation, path: path.to_path_buf(), errno };
}
pub fn means_feature_missing(&self) -> bool {
return [libc::ENOTTY, libc::EOPNOTSUPP, libc::EINVAL, libc::EXDEV, libc::ENOSYS].contains(&self.errno);
}
}
impl fmt::Display for PrimitiveError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
return write!(
formatter,
"{} on {} failed: {} (errno {})",
self.operation,
self.path.display(),
std::io::Error::from_raw_os_error(self.errno),
self.errno
);
}
}
impl std::error::Error for PrimitiveError {}
pub fn c_path(operation: &'static str, path: &Path) -> Result<CString, PrimitiveError> {
return CString::new(path.as_os_str().as_bytes())
.map_err(|_| { return PrimitiveError { operation, path: path.to_path_buf(), errno: libc::EINVAL }; });
}
#[cfg(test)]
#[path = "fs_primitive_error_tests.rs"]
mod tests;