108 lines
3.3 KiB
Rust
108 lines
3.3 KiB
Rust
use std::sync::Arc;
|
|
|
|
use annotate_snippets::AnnotationKind;
|
|
use annotate_snippets::Level;
|
|
use annotate_snippets::Renderer;
|
|
use annotate_snippets::Snippet;
|
|
use thiserror::Error;
|
|
|
|
use crate::input::NomoInput;
|
|
use crate::lexer::ParseError;
|
|
use crate::parser::AstError;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub struct AstFailure {
|
|
errors: Vec<AstError>,
|
|
}
|
|
|
|
impl std::fmt::Display for AstFailure {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str("TODO")
|
|
}
|
|
}
|
|
|
|
impl AstFailure {
|
|
pub(crate) fn from_errors(errors: Vec<AstError>) -> AstFailure {
|
|
AstFailure { errors }
|
|
}
|
|
|
|
pub fn to_report(&self, source: &str) -> String {
|
|
let reports = self
|
|
.errors
|
|
.iter()
|
|
.map(|error| {
|
|
annotate_snippets::Level::ERROR
|
|
.primary_title(
|
|
error
|
|
.message
|
|
.as_deref()
|
|
.unwrap_or("An error occurred while producing an Ast"),
|
|
)
|
|
.element(
|
|
annotate_snippets::Snippet::source(source).annotation(
|
|
annotate_snippets::AnnotationKind::Primary
|
|
.span(error.span.clone().map(|s| s.range).unwrap_or_else(|| 0..0)),
|
|
),
|
|
)
|
|
.elements(
|
|
error
|
|
.help
|
|
.as_ref()
|
|
.map(|help| annotate_snippets::Level::HELP.message(help)),
|
|
)
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let renderer = annotate_snippets::Renderer::styled()
|
|
.decor_style(annotate_snippets::renderer::DecorStyle::Unicode);
|
|
renderer.render(&reports)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Error)]
|
|
pub struct ParseFailure {
|
|
input: Arc<str>,
|
|
errors: Vec<ParseError>,
|
|
}
|
|
|
|
impl std::fmt::Display for ParseFailure {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str(&self.to_report())
|
|
}
|
|
}
|
|
|
|
impl ParseFailure {
|
|
pub(crate) fn from_errors(errors: Vec<ParseError>, input: NomoInput) -> ParseFailure {
|
|
ParseFailure {
|
|
input: Arc::from(input.to_string()),
|
|
errors,
|
|
}
|
|
}
|
|
|
|
pub fn to_report(&self) -> String {
|
|
let reports = self
|
|
.errors
|
|
.iter()
|
|
.map(|error| {
|
|
Level::ERROR
|
|
.primary_title(
|
|
error
|
|
.message
|
|
.as_deref()
|
|
.unwrap_or("An error occurred while parsing"),
|
|
)
|
|
.element(
|
|
Snippet::source(self.input.as_ref()).annotation(
|
|
AnnotationKind::Primary
|
|
.span(error.span.clone().map(|s| s.range).unwrap_or_else(|| 0..0)),
|
|
),
|
|
)
|
|
.elements(error.help.as_ref().map(|help| Level::HELP.message(help)))
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let renderer =
|
|
Renderer::styled().decor_style(annotate_snippets::renderer::DecorStyle::Unicode);
|
|
renderer.render(&reports)
|
|
}
|
|
}
|