use std::fmt::{
self,
Display,
};
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum RequestError {
#[error("The request is not supported. `{0}`")]
NotSupported(&'static str),
#[error("The request was ignored by the OS")]
Ignored,
#[error("OS specific error. `{0}`")]
Os(#[from] OsError),
}
#[derive(thiserror::Error, Debug)]
pub struct OsError {
line: u32,
file: &'static str,
error: Box<dyn std::error::Error + Send + Sync + 'static>,
}
impl OsError {
pub fn new(
line: u32,
file: &'static str,
error: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
) -> Self {
Self {
line,
file,
error: error.into(),
}
}
}
impl Display for OsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error))
}
}
pub trait MapToOSError<T, E> {
fn map_to_os_err(self) -> Result<T, OsError>
where
Self: Sized;
}
impl<T, E> MapToOSError<T, E> for Result<T, E>
where
E: std::error::Error + Send + Sync + 'static,
{
fn map_to_os_err(self) -> Result<T, OsError>
where
Self: Sized,
{
match self {
Ok(t) => Ok(t),
Err(e) => Err(crate::os_error!(e)),
}
}
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! os_error {
($error:expr) => {{ $crate::error::OsError::new(line!(), file!(), $error) }};
}