use crate::AddressContext;
#[derive(thiserror::Error, Debug)]
pub enum VmiError {
#[error(transparent)]
Driver(Box<dyn std::error::Error + Send + Sync>),
#[error(transparent)]
Os(Box<dyn std::error::Error + Send + Sync>),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Isr(#[from] isr_macros::Error),
#[error("translation error ({:?}, len: {})", .0[0], .0.len())]
Translation(PageFaults),
#[error("invalid address width")]
InvalidAddressWidth,
#[error("invalid timeout")]
InvalidTimeout,
#[error("operation not supported")]
NotSupported,
#[error("out of bounds")]
OutOfBounds,
#[error("translation root not present")]
RootNotPresent,
#[error("operation timed out")]
Timeout,
#[error("view not found")]
ViewNotFound,
#[error("{0}")]
Other(&'static str),
}
pub type PageFaults = smallvec::SmallVec<[AddressContext; 1]>;
impl VmiError {
pub fn driver<E>(err: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Driver(Box::new(err))
}
pub fn os<E>(err: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Os(Box::new(err))
}
pub fn page_fault(pf: impl Into<AddressContext>) -> Self {
Self::Translation(smallvec::smallvec![pf.into()])
}
pub fn page_faults(pfs: impl IntoIterator<Item = AddressContext>) -> Self {
Self::Translation(pfs.into_iter().collect())
}
}