dust/dust-lang/src/dust_error.rs

50 lines
1.5 KiB
Rust
Raw Normal View History

2024-08-09 01:59:09 +00:00
//! Top-level error handling for the Dust language.
2024-08-09 01:47:49 +00:00
use annotate_snippets::{Level, Renderer, Snippet};
2024-08-09 00:58:56 +00:00
use std::{error::Error, fmt::Display};
2024-08-09 05:55:34 +00:00
use crate::VmError;
2024-08-09 00:58:56 +00:00
2024-08-09 01:59:09 +00:00
/// An error that occurred during the execution of the Dust language and its
/// corresponding source code.
2024-08-09 00:58:56 +00:00
#[derive(Debug, Clone, PartialEq)]
pub struct DustError<'src> {
vm_error: VmError,
source: &'src str,
}
2024-08-09 01:47:49 +00:00
impl<'src> DustError<'src> {
pub fn new(vm_error: VmError, source: &'src str) -> Self {
Self { vm_error, source }
}
pub fn report(&self) -> String {
let title = match &self.vm_error {
VmError::AnaylyzerError(_) => "Analyzer error",
VmError::ParseError(_) => "Parse error",
2024-08-09 04:31:38 +00:00
VmError::ValueError { .. } => "Value error",
2024-08-09 05:43:58 +00:00
VmError::BuiltInFunctionError { .. } => "Runtime error",
2024-08-09 01:47:49 +00:00
_ => "Analysis Failure",
};
2024-08-09 05:43:58 +00:00
let span = self.vm_error.position();
2024-08-09 01:47:49 +00:00
let label = self.vm_error.to_string();
let message = Level::Error.title(title).snippet(
Snippet::source(self.source).annotation(Level::Info.span(span.0..span.1).label(&label)),
);
let renderer = Renderer::styled();
format!("{}", renderer.render(message))
}
}
2024-08-09 00:58:56 +00:00
impl Error for DustError<'_> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.vm_error)
}
}
impl Display for DustError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}\n{}", self.vm_error, self.source)
}
}