2022-04-02 21:23:47 +02:00
|
|
|
use std::error::Error;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub struct Location<'a> {
|
|
|
|
pub line: usize,
|
|
|
|
pub col: usize,
|
|
|
|
pub file: Option<&'a str>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct OwnedLocation {
|
|
|
|
pub line: usize,
|
|
|
|
pub col: usize,
|
|
|
|
pub file: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<Location<'a>> for OwnedLocation {
|
|
|
|
fn from(l: Location<'a>) -> OwnedLocation {
|
|
|
|
OwnedLocation {
|
|
|
|
line: l.line,
|
|
|
|
col: l.col,
|
|
|
|
file: l.file.map(|v| v.to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<&'a OwnedLocation> for Location<'a> {
|
|
|
|
fn from(l: &'a OwnedLocation) -> Location<'a> {
|
|
|
|
Location {
|
|
|
|
line: l.line,
|
|
|
|
col: l.col,
|
2022-04-03 22:07:19 +02:00
|
|
|
file: l.file.as_deref(),
|
2022-04-02 21:23:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait ErrorWithLocation: Error {
|
|
|
|
fn get_location(&self) -> Location;
|
|
|
|
}
|
2022-04-03 21:54:26 +02:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ErrorLocationWrapper<T: Error> {
|
2022-04-06 20:58:05 +02:00
|
|
|
pub inner: T,
|
2022-04-03 21:54:26 +02:00
|
|
|
location: OwnedLocation,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Error> ErrorLocationWrapper<T> {
|
|
|
|
pub fn new(inner: T, location: OwnedLocation) -> Self {
|
|
|
|
Self { inner, location }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: std::error::Error> ErrorWithLocation for ErrorLocationWrapper<T> {
|
|
|
|
fn get_location(&self) -> Location {
|
|
|
|
(&self.location).into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Error> std::fmt::Display for ErrorLocationWrapper<T> {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"An error occured: {} \n On line: {}, col: {}",
|
|
|
|
self.inner, self.location.line, self.location.col
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Error> Error for ErrorLocationWrapper<T> {
|
|
|
|
fn cause(&self) -> Option<&dyn Error> {
|
|
|
|
Some(&self.inner)
|
|
|
|
}
|
|
|
|
}
|
2022-04-19 00:46:33 +02:00
|
|
|
|
|
|
|
impl<'a> Location<'a> {
|
|
|
|
pub fn wrap<T: Error>(self, err: T) -> ErrorLocationWrapper<T> {
|
|
|
|
ErrorLocationWrapper::new(err, self.into())
|
|
|
|
}
|
|
|
|
}
|