use std::io;
use rustix::io::Errno;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum CoreError {
#[error("`{path}` is not a DRM device")]
NotADrmDevice {
path: String,
},
#[error("no properties cached for object {object_id}")]
NoSuchObject {
object_id: u32,
},
#[error("object {object_id} has no property `{name}`")]
NoSuchProperty {
object_id: u32,
name: String,
},
#[error("device holds no descriptor")]
NoDevice,
#[error("not DRM master")]
NotMaster,
#[error("DRM operation failed: {0}")]
Io(#[from] Errno),
}
impl CoreError {
pub(crate) fn from_errno(errno: Errno) -> Self {
if errno == Errno::ACCESS {
Self::NotMaster
} else {
Self::Io(errno)
}
}
pub(crate) fn from_io(error: &io::Error) -> Self {
Errno::from_io_error(error).map_or(Self::NoDevice, Self::from_errno)
}
#[must_use]
pub const fn errno(&self) -> Option<Errno> {
match self {
Self::Io(errno) => Some(*errno),
Self::NotMaster => Some(Errno::ACCESS),
_ => None,
}
}
}
impl From<CoreError> for io::Error {
fn from(e: CoreError) -> Self {
e.errno().map_or_else(
|| Self::from(io::ErrorKind::NotFound),
|errno| Self::from_raw_os_error(errno.raw_os_error()),
)
}
}
pub type Result<T> = std::result::Result<T, CoreError>;