dust/dust-lang/src/dust_error.rs

70 lines
2.8 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 01:47:49 +00:00
use crate::{AnalyzerError, 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 01:47:49 +00:00
VmError::BuiltInFunctionCallError(_) => "Runtime error",
_ => "Analysis Failure",
};
let span = match &self.vm_error {
VmError::AnaylyzerError(analyzer_error) => match analyzer_error {
AnalyzerError::ExpectedBoolean { position, .. } => position,
AnalyzerError::ExpectedFunction { position, .. } => position,
AnalyzerError::ExpectedIdentifier { position, .. } => position,
AnalyzerError::ExpectedIdentifierOrValue { position, .. } => position,
AnalyzerError::ExpectedIntegerOrFloat { position, .. } => position,
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => position,
AnalyzerError::UnexpectedIdentifier { position, .. } => position,
},
2024-08-09 04:49:17 +00:00
VmError::ParseError(parse_error) => &parse_error.position(),
2024-08-09 04:31:38 +00:00
VmError::ValueError { position, .. } => position,
2024-08-09 01:47:49 +00:00
VmError::BuiltInFunctionCallError(_) => todo!(),
VmError::ExpectedIdentifier { position } => position,
VmError::ExpectedIdentifierOrInteger { position } => position,
VmError::ExpectedInteger { position } => position,
VmError::ExpectedFunction { position, .. } => position,
VmError::ExpectedList { position } => position,
VmError::ExpectedValue { position } => position,
2024-08-09 04:49:17 +00:00
VmError::UndefinedIdentifier { position, .. } => 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)
}
}