Add proper impl for templating

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-06 12:56:16 +01:00
parent 1ee7611981
commit 4470af3926
5 changed files with 85 additions and 27 deletions

View file

@ -4,6 +4,7 @@ use annotate_snippets::AnnotationKind;
use annotate_snippets::Level;
use annotate_snippets::Renderer;
use annotate_snippets::Snippet;
use thiserror::Error;
use winnow::LocatingSlice;
use winnow::Parser;
use winnow::RecoverableParser;
@ -37,16 +38,22 @@ use crate::resume_after_cut;
type Input<'input> = Recoverable<LocatingSlice<TempleInput>, ParseError>;
type PResult<'input, T> = Result<T, ParseError>;
#[derive(Debug)]
#[derive(Debug, Error)]
pub struct ParseFailure {
source: Arc<str>,
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: &str) -> ParseFailure {
fn from_errors(errors: Vec<ParseError>, input: TempleInput) -> ParseFailure {
ParseFailure {
source: Arc::from(input.to_string()),
input: Arc::from(input.to_string()),
errors,
}
}
@ -64,7 +71,7 @@ impl ParseFailure {
.unwrap_or("An error occurred while parsing"),
)
.element(
Snippet::source(self.source.as_ref()).annotation(
Snippet::source(self.input.as_ref()).annotation(
AnnotationKind::Primary
.span(error.span.clone().map(|s| s.range).unwrap_or_else(|| 0..0)),
),
@ -294,9 +301,9 @@ impl TemplateToken {
}
}
pub fn parse(input: &str) -> Result<ParsedTemplate, ParseFailure> {
pub fn parse(input: TempleInput) -> Result<ParsedTemplate, ParseFailure> {
let (_remaining, val, errors) =
parse_tokens.recoverable_parse(LocatingSlice::new(TempleInput::from(input)));
parse_tokens.recoverable_parse(LocatingSlice::new(input.clone()));
if errors.is_empty()
&& let Some(val) = val
@ -418,7 +425,7 @@ mod tests {
#[test]
fn parse_simple() {
let input = "Hello There";
let output = parse(input);
let output = parse(input.into());
insta::assert_debug_snapshot!(output, @r#"
Ok(
@ -437,7 +444,7 @@ mod tests {
#[test]
fn parse_interpolate() {
let input = "Hello {{ there }}";
let output = parse(input);
let output = parse(input.into());
insta::assert_debug_snapshot!(output, @r#"
Ok(
@ -480,12 +487,12 @@ mod tests {
#[test]
fn parse_interpolate_bad() {
let input = "Hello {{ the2re }} {{ the@re }}";
let output = parse(input);
let output = parse(input.into());
insta::assert_debug_snapshot!(output, @r#"
Err(
ParseFailure {
source: "Hello {{ the2re }} {{ the@re }}",
input: "Hello {{ the2re }} {{ the@re }}",
errors: [
ParseError {
message: Some(