use std::{
error,
fmt::{self, Display, Formatter},
};
#[macro_export]
macro_rules! error {
($($arg:tt)*) => {{
let error = format!($($arg)*);
$crate::error::Error::new(error, file!(), line!())
}};
}
#[derive(Debug)]
pub struct Error {
error: String,
source: Option<Box<dyn std::error::Error>>,
file: &'static str,
line: u32,
}
impl Error {
#[doc(hidden)]
pub fn new<T>(desc: T, file: &'static str, line: u32) -> Self
where
T: ToString,
{
Self { error: desc.to_string(), source: None, file, line }
}
#[doc(hidden)]
pub fn with_error<T>(error: T, file: &'static str, line: u32) -> Self
where
T: error::Error + 'static,
{
let error = Box::new(error);
Self { error: format!("{error}"), source: Some(error), file, line }
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{} at {}:{}", self.error, self.file, self.line)
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
let source = self.source.as_ref()?;
Some(source.as_ref())
}
}