From 13eb4ca1d06af864d95892153cf8a42425f24db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Sun, 8 Mar 2026 20:02:33 +0100 Subject: [PATCH] Add else parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- src/parser/mod.rs | 58 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 14d9a41..c80b5ec 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -206,6 +206,7 @@ pub enum TokenKind { Whitespace, Invalid, ConditionalIf, + ConditionalElse, End, Literal(TokenLiteral), } @@ -290,6 +291,7 @@ impl TemplateToken { whitespace => TokenKind::Whitespace, invalid => TokenKind::Invalid, conditional_if => TokenKind::ConditionalIf, + conditional_else => TokenKind::ConditionalElse, end => TokenKind::End, } @@ -344,7 +346,7 @@ fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec, _) = get_tokens @@ -369,13 +371,14 @@ fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { +fn parse_block_token<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { trace( - "parse_interpolate_token", + "parse_block_token", alt(( parse_ident, parse_literal, - parse_condition, + parse_condition_if, + parse_condition_else, parse_end, parse_whitespace, )), @@ -385,7 +388,7 @@ fn parse_interpolate_token<'input>(input: &mut Input<'input>) -> PResult<'input, fn parse_literal<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { trace( - "parse_condition", + "parse_literal", alt((parse_boolean,)) .with_taken() .map(|(lit, span)| TemplateToken::literal(lit, span)), @@ -401,12 +404,24 @@ fn parse_boolean<'input>(input: &mut Input<'input>) -> PResult<'input, TokenLite .parse_next(input) } -fn parse_condition<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { - trace("parse_condition", "if".map(TemplateToken::conditional_if)).parse_next(input) +fn parse_condition_if<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { + trace( + "parse_condition_if", + "if".map(TemplateToken::conditional_if), + ) + .parse_next(input) +} + +fn parse_condition_else<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { + trace( + "parse_condition_else", + "else".map(TemplateToken::conditional_else), + ) + .parse_next(input) } fn parse_end<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { - trace("parse_condition", "end".map(TemplateToken::end)).parse_next(input) + trace("parse_end", "end".map(TemplateToken::end)).parse_next(input) } fn parse_whitespace<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> { @@ -436,9 +451,14 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok } fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> { - peek(not(alt((parse_literal, parse_condition, parse_end)))) - .context(ParseError::ctx().msg("Expected an ident, but found a literal instead")) - .parse_next(input)?; + peek(not(alt(( + parse_literal, + parse_condition_if, + parse_condition_else, + parse_end, + )))) + .context(ParseError::ctx().msg("Expected an ident, but found a literal instead")) + .parse_next(input)?; take_while(1.., |c: char| c.is_alphanumeric() || "_".contains(c)).parse_next(input) } @@ -540,7 +560,7 @@ mod tests { #[test] fn parse_simple_condition() { - let input = "{{ if true }} Hello! {{ end }}"; + let input = "{{ if true }} Hello! {{ else }} Bye {{ end }}"; let output = parse(input.into()); insta::assert_debug_snapshot!(output, @r#" @@ -559,9 +579,17 @@ mod tests { " " (20..21), "{{" (21..23), " " (23..24), - "end" (24..27), - " " (27..28), - "}}" (28..30), + "else" (24..28), + " " (28..29), + "}}" (29..31), + " " (31..32), + "Bye" (32..35), + " " (35..36), + "{{" (36..38), + " " (38..39), + "end" (39..42), + " " (42..43), + "}}" (43..45), ], }, )