Fix issue with repeating {{ else }} blocks

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-09 16:02:55 +01:00
parent 462355b6f2
commit b0620a00d5
3 changed files with 63 additions and 28 deletions

View file

@ -345,39 +345,67 @@ fn parse_conditional_chain<'input>(
chain.push(if_block);
loop {
let (content, end_block): (Vec<_>, _) = repeat_till(
0..,
parse_ast,
trace(
"conditional_chain_else/end",
alt((parse_end, parse_conditional_else)),
),
)
.parse_next(input)?;
let content = resume_after_cut(
inner_conditional_chain,
repeat_till(0.., any, parse_end).map(|((), _)| ()),
)
.parse_next(input)?;
chain.push(TemplateAstExpr::ConditionalContent { content });
let is_end = if let TemplateAstExpr::Block { ref expression, .. } = end_block
&& let TemplateAstExpr::EndBlock = &**expression
{
true
} else {
false
};
chain.push(end_block);
if is_end {
break;
}
}
chain.extend(content.into_iter().flatten());
Ok(TemplateAstExpr::ConditionalChain { chain })
})
.parse_next(input)
}
fn inner_conditional_chain<'input>(
input: &mut Input<'input>,
) -> Result<Vec<TemplateAstExpr<'input>>, AstError> {
let mut needs_end = false;
let mut chain = vec![];
loop {
let (content, end_block): (Vec<_>, _) = repeat_till(
0..,
parse_ast,
trace(
"conditional_chain_else/end",
alt((parse_end, parse_conditional_else)),
),
)
.parse_next(input)?;
chain.push(TemplateAstExpr::ConditionalContent { content });
let is_end = if let TemplateAstExpr::Block { ref expression, .. } = end_block
&& let TemplateAstExpr::EndBlock = &**expression
{
true
} else {
false
};
if !is_end && needs_end {
return Err(AstError::from_input(input).cut());
}
if let TemplateAstExpr::Block { expression, .. } = &end_block
&& let TemplateAstExpr::ElseConditional { expression: None } = &**expression
{
needs_end = true;
}
chain.push(end_block);
if is_end {
break;
}
}
Ok(chain)
}
fn parse_conditional_if<'input>(
input: &mut Input<'input>,
) -> Result<TemplateAstExpr<'input>, AstError> {