crftng-intrprtrs/src/error.rs

74 lines
1.4 KiB
Rust

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,
file: l.file.as_deref(),
}
}
}
pub trait ErrorWithLocation: Error {
fn get_location(&self) -> Location;
}
#[derive(Debug)]
pub struct ErrorLocationWrapper<T: Error> {
pub inner: T,
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)
}
}