use core::error::Error;
use alloc::{boxed::Box, string::ToString};
use irid_syscall::SystemError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum IOError {
#[error("operation not permitted")]
NotPermitted,
#[error("no such file or directory")]
NotFound,
#[error("process not found")]
ProcessNotFound,
#[error("interrupted")]
Interrupted,
#[error("input/output error")]
IO,
#[error("file already exists")]
AlreadyExists,
#[error("no such device")]
NoDevice,
#[error("file system or resource is read-only")]
ReadOnlyFileSystem,
#[error("unknown system error: {0}")]
Unknown(isize),
#[error("end of file reached")]
EndOfFile,
#[error("command not supported by device")]
NotTypewriter,
#[error("{1}: {0}")]
WithPath(Box<str>, #[source] Box<dyn Error>)
}
pub(crate) trait WithPath {
type Output;
fn with_path(self, context: impl ToString) -> Self::Output;
}
impl <T> WithPath for Result<T, IOError> {
type Output = Result<T, IOError>;
fn with_path(self, context: impl ToString) -> Self {
self.map_err(|err| IOError::WithPath(context.to_string().into_boxed_str(), Box::new(err)))
}
}
impl From<SystemError> for IOError {
fn from(value: SystemError) -> Self {
let value: isize = value.into();
match value {
1 => Self::NotPermitted,
2 => Self::NotFound,
3 => Self::ProcessNotFound,
4 => Self::Interrupted,
5 => Self::IO,
17 => Self::AlreadyExists,
19 => Self::NoDevice,
25 => Self::NotTypewriter,
30 => Self::ReadOnlyFileSystem,
_ => Self::Unknown(value)
}
}
}