use std::{self, path::PathBuf};
use crate::core::deviceinfo::DeviceInfo;
#[derive(Clone, Debug)]
pub enum Error {
ContextInit(String),
InvalidArgument(String),
Ioctl(
u8,
Option<Box<DeviceInfo>>,
Option<Box<DeviceInfo>>,
Box<nix::Error>,
),
IoctlResultTooLarge,
MetadataIo(PathBuf, String),
GeneralIo(String),
UdevSync(String),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::ContextInit(err) => {
write!(f, "DM context not initialized due to IO error: {err}")
}
Error::InvalidArgument(err) => write!(f, "invalid argument: {err}"),
Error::Ioctl(op, hdr_in, hdr_out, err) => write!(
f,
"low-level ioctl error due to nix error; ioctl number: {op}, input header: {hdr_in:?}, header result: {hdr_out:?}, error: {err}"
),
Error::IoctlResultTooLarge => write!(
f,
"ioctl result too large for maximum buffer size: {} bytes",
u32::MAX
),
Error::MetadataIo(device_path, err) => write!(
f,
"failed to stat metadata for device at {} due to IO error: {}",
device_path.display(),
err
),
Error::GeneralIo(err) => {
write!(f, "failed to perform operation due to IO error: {err}")
}
Error::UdevSync(err) => {
write!(f, "failed to perform udev sync operation: {err}")
}
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Ioctl(_, _, _, err) => Some(err),
_ => None,
}
}
}