Move ParseFailure to errors

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-16 09:46:25 +01:00
parent 058e6be516
commit 560d37f633
3 changed files with 59 additions and 50 deletions

View file

@ -1,5 +1,13 @@
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)]
@ -50,3 +58,51 @@ impl AstFailure {
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)
}
}

View file

@ -39,60 +39,13 @@ use winnow::token::take_until;
use winnow::token::take_while;
use crate::SourceSpan;
use crate::errors::ParseFailure;
use crate::input::NomoInput;
use crate::resume_after_cut;
type Input<'input> = Recoverable<LocatingSlice<NomoInput>, ParseError>;
type PResult<'input, T> = Result<T, ParseError>;
#[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 {
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)
}
}
#[derive(Debug, Clone)]
pub struct ParseError {
pub(crate) message: Option<String>,

View file

@ -26,7 +26,7 @@
feature = "document-features",
cfg_attr(doc, doc = ::document_features::document_features!())
)]
//!
//!
use std::collections::HashMap;
@ -84,7 +84,7 @@ pub enum NomoError {
ParseError {
#[from]
#[expect(missing_docs)]
source: lexer::ParseFailure,
source: errors::ParseFailure,
},
/// Invalid Template
AstError {