Split up if chains more
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
383f543119
commit
c9314a3d9b
4 changed files with 90 additions and 21 deletions
|
|
@ -228,10 +228,12 @@ pub enum TemplateAstExpr<'input> {
|
|||
},
|
||||
IfConditional {
|
||||
if_block: Box<TemplateAstExpr<'input>>,
|
||||
},
|
||||
ConditionalContent {
|
||||
content: Vec<TemplateAstExpr<'input>>,
|
||||
},
|
||||
ElseConditional {
|
||||
expression: Vec<TemplateAstExpr<'input>>,
|
||||
expression: Option<Box<TemplateAstExpr<'input>>>,
|
||||
},
|
||||
Invalid(&'input [TemplateToken]),
|
||||
EndBlock,
|
||||
|
|
@ -314,21 +316,45 @@ fn parse_conditional_chain<'input>(
|
|||
input: &mut Input<'input>,
|
||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||
trace("conditional_chain", |input: &mut Input<'input>| {
|
||||
let if_block = parse_conditional.map(Box::new).parse_next(input)?;
|
||||
let if_block = parse_conditional_if.map(Box::new).parse_next(input)?;
|
||||
let mut chain = vec![];
|
||||
|
||||
let (content, end_block): (Vec<_>, _) =
|
||||
repeat_till(0.., parse_ast, parse_end).parse_next(input)?;
|
||||
chain.push(TemplateAstExpr::IfConditional { 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)?;
|
||||
|
||||
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(TemplateAstExpr::IfConditional { if_block, content });
|
||||
chain.push(end_block);
|
||||
|
||||
if dbg!(is_end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TemplateAstExpr::ConditionalChain { chain })
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_conditional<'input>(
|
||||
fn parse_conditional_if<'input>(
|
||||
input: &mut Input<'input>,
|
||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||
trace(
|
||||
|
|
@ -344,6 +370,27 @@ fn parse_conditional<'input>(
|
|||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_conditional_else<'input>(
|
||||
input: &mut Input<'input>,
|
||||
) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||
trace(
|
||||
"conditional_else",
|
||||
parse_block(
|
||||
preceded(
|
||||
surrounded(ws, TokenKind::ConditionalElse),
|
||||
opt(preceded(
|
||||
TokenKind::ConditionalIf,
|
||||
cut_err(surrounded(ws, parse_value_expression)).map(Box::new),
|
||||
)),
|
||||
)
|
||||
.map(|else_expr| TemplateAstExpr::ElseConditional {
|
||||
expression: else_expr,
|
||||
}),
|
||||
),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_end<'input>(input: &mut Input<'input>) -> Result<TemplateAstExpr<'input>, AstError> {
|
||||
trace(
|
||||
"end",
|
||||
|
|
@ -440,6 +487,18 @@ mod tests {
|
|||
use crate::ast::parse_end;
|
||||
use crate::parser::TokenKind;
|
||||
|
||||
fn panic_pretty<'a>(
|
||||
input: &'_ str,
|
||||
tokens: Result<TemplateAst<'a>, AstFailure>,
|
||||
) -> TemplateAst<'a> {
|
||||
match tokens {
|
||||
Ok(ast) => ast,
|
||||
Err(failure) => {
|
||||
panic!("{}", failure.to_report(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_only_content() {
|
||||
let input = "Hello World";
|
||||
|
|
@ -493,7 +552,7 @@ mod tests {
|
|||
|
||||
let parsed = crate::parser::parse(input.into()).unwrap();
|
||||
|
||||
let ast = parse(parsed.tokens()).unwrap();
|
||||
let ast = panic_pretty(input, parse(parsed.tokens()));
|
||||
|
||||
insta::assert_debug_snapshot!(ast, @r#"
|
||||
TemplateAst {
|
||||
|
|
@ -510,6 +569,8 @@ mod tests {
|
|||
[Whitespace]" " (12..13),
|
||||
),
|
||||
},
|
||||
},
|
||||
ConditionalContent {
|
||||
content: [
|
||||
StaticContent(
|
||||
[Content]"Hiii" (13..17),
|
||||
|
|
@ -530,18 +591,6 @@ mod tests {
|
|||
"#);
|
||||
}
|
||||
|
||||
fn panic_pretty<'a>(
|
||||
input: &'_ str,
|
||||
tokens: Result<TemplateAst<'a>, AstFailure>,
|
||||
) -> TemplateAst<'a> {
|
||||
match tokens {
|
||||
Ok(ast) => ast,
|
||||
Err(failure) => {
|
||||
panic!("{}", failure.to_report(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_invalid_action() {
|
||||
let input = r#"{{ value }}
|
||||
|
|
@ -624,4 +673,13 @@ mod tests {
|
|||
)
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_empty_output() {
|
||||
let input = "{{ if foo }}{{ end }}";
|
||||
|
||||
let parsed = crate::parser::parse(input.into()).unwrap();
|
||||
|
||||
panic_pretty(input, parse(parsed.tokens()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ TemplateAst {
|
|||
[Whitespace]"\n " (12..25),
|
||||
),
|
||||
},
|
||||
},
|
||||
ConditionalContent {
|
||||
content: [
|
||||
ConditionalChain {
|
||||
chain: [
|
||||
|
|
@ -29,6 +31,8 @@ TemplateAst {
|
|||
[Whitespace]"\n " (37..54),
|
||||
),
|
||||
},
|
||||
},
|
||||
ConditionalContent {
|
||||
content: [
|
||||
StaticContent(
|
||||
[Content]"Hiii" (54..58),
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ fn emit_ast_expr(
|
|||
let mut chain = chain.iter();
|
||||
let Some(TemplateAstExpr::IfConditional {
|
||||
if_block: expression,
|
||||
content,
|
||||
}) = chain.next()
|
||||
else {
|
||||
unreachable!("First element in conditional chain should be an IfConditional");
|
||||
|
|
@ -107,6 +106,10 @@ fn emit_ast_expr(
|
|||
unreachable!("The end of an IfConditional must be a Block");
|
||||
};
|
||||
|
||||
let Some(TemplateAstExpr::ConditionalContent { content }) = chain.next() else {
|
||||
unreachable!("The end of an IfConditional must be a Block");
|
||||
};
|
||||
|
||||
if let Some(ws) = prev_whitespace_content {
|
||||
eval.push(Instruction::AppendContent {
|
||||
content: ws.source().clone(),
|
||||
|
|
@ -163,6 +166,7 @@ fn emit_ast_expr(
|
|||
TemplateAstExpr::Block { .. }
|
||||
| TemplateAstExpr::EndBlock
|
||||
| TemplateAstExpr::IfConditional { .. }
|
||||
| TemplateAstExpr::ConditionalContent { .. }
|
||||
| TemplateAstExpr::ElseConditional { .. }
|
||||
| TemplateAstExpr::Invalid { .. }
|
||||
| TemplateAstExpr::VariableAccess { .. } => eval.push(Instruction::Abort),
|
||||
|
|
@ -191,6 +195,7 @@ fn emit_expr_load(
|
|||
TemplateAstExpr::EndBlock => todo!(),
|
||||
TemplateAstExpr::Block { .. } => todo!(),
|
||||
TemplateAstExpr::IfConditional { .. } => todo!(),
|
||||
TemplateAstExpr::ConditionalContent { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ TemplateAst {
|
|||
[Whitespace]"\n " (13..18),
|
||||
),
|
||||
},
|
||||
},
|
||||
ConditionalContent {
|
||||
content: [
|
||||
StaticContent(
|
||||
[Content]"Hello World!" (18..30),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue