diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index feb13d04..708d8809 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -369,24 +369,20 @@ pub struct Cond<'a> { impl<'a> Cond<'a> { fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { - let mut p = tuple(( + let (i, (_, pws, cond, nws, _, nodes)) = tuple(( |i| s.tag_block_start(i), opt(Whitespace::parse), - ws(alt((keyword("else"), |i| { - let _ = keyword("elif")(i)?; - Err(nom::Err::Failure(ErrorContext::new( - "unknown `elif` keyword; did you mean `else if`?", - i, - ))) - }))), - cut(tuple(( - opt(|i| CondTest::parse(i, s)), - opt(Whitespace::parse), - |i| s.tag_block_end(i), - cut(|i| Node::many(i, s)), - ))), - )); - let (i, (_, pws, _, (cond, nws, _, nodes))) = p(i)?; + alt(( + preceded(ws(keyword("else")), opt(|i| CondTest::parse(i, s))), + preceded( + ws(keyword("elif")), + cut(map(|i| CondTest::parse_cond(i, s), Some)), + ), + )), + opt(Whitespace::parse), + cut(|i| s.tag_block_end(i)), + cut(|i| Node::many(i, s)), + ))(i)?; Ok(( i, Self { @@ -406,18 +402,18 @@ pub struct CondTest<'a> { impl<'a> CondTest<'a> { fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { - let mut p = preceded( - ws(keyword("if")), - cut(tuple(( - opt(delimited( - ws(alt((keyword("let"), keyword("set")))), - ws(|i| Target::parse(i, s)), - ws(char('=')), - )), - ws(|i| Expr::parse(i, s.level.get())), - ))), - ); - let (i, (target, expr)) = p(i)?; + preceded(ws(keyword("if")), cut(|i| Self::parse_cond(i, s)))(i) + } + + fn parse_cond(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { + let (i, (target, expr)) = pair( + opt(delimited( + ws(alt((keyword("let"), keyword("set")))), + ws(|i| Target::parse(i, s)), + ws(char('=')), + )), + ws(|i| Expr::parse(i, s.level.get())), + )(i)?; Ok((i, Self { target, expr })) } } diff --git a/book/src/template_syntax.md b/book/src/template_syntax.md index 351cbff8..d81229b6 100644 --- a/book/src/template_syntax.md +++ b/book/src/template_syntax.md @@ -459,6 +459,8 @@ and is used as you might expect: No users {% else if users.len() == 1 %} 1 user +{% elif users.len() == 2 %} + 2 users {% else %} {{ users.len() }} users {% endif %} diff --git a/testing/tests/if.rs b/testing/tests/if.rs new file mode 100644 index 00000000..bbe2865d --- /dev/null +++ b/testing/tests/if.rs @@ -0,0 +1,26 @@ +use askama::Template; + +#[derive(Template)] +#[template( + source = r#"{%- if s == "" -%} +empty +{%- else if s == "b" -%} +b +{%- elif s == "c" -%} +c +{%- else -%} +else +{%- endif -%}"#, + ext = "txt" +)] +struct If<'a> { + s: &'a str, +} + +#[test] +fn test_if() { + assert_eq!(If { s: "" }.render().unwrap(), "empty"); + assert_eq!(If { s: "b" }.render().unwrap(), "b"); + assert_eq!(If { s: "c" }.render().unwrap(), "c"); + assert_eq!(If { s: "d" }.render().unwrap(), "else"); +} diff --git a/testing/tests/if_let.rs b/testing/tests/if_let.rs index 3e4e2b5e..d3834181 100644 --- a/testing/tests/if_let.rs +++ b/testing/tests/if_let.rs @@ -107,3 +107,24 @@ fn test_if_let_else() { }; assert_eq!(s.render().unwrap(), "fail"); } + +#[derive(Template)] +#[template( + source = r#"{%- if s.is_none() -%} +empty +{%- elif let Some(a) = s -%} +{{a}} +{%- else -%} +else +{%- endif -%}"#, + ext = "txt" +)] +struct Elif<'a> { + s: Option<&'a str>, +} + +#[test] +fn test_elif() { + assert_eq!(Elif { s: None }.render().unwrap(), "empty"); + assert_eq!(Elif { s: Some("tada") }.render().unwrap(), "tada"); +} diff --git a/testing/tests/ui/elif.rs b/testing/tests/ui/elif.rs deleted file mode 100644 index 650f2923..00000000 --- a/testing/tests/ui/elif.rs +++ /dev/null @@ -1,8 +0,0 @@ -use askama::Template; - -#[derive(Template)] -#[template(source = "{% if true %}{% elif false %}{% endif %}", ext = "html")] -struct UnknownElif; - -fn main() { -} diff --git a/testing/tests/ui/elif.stderr b/testing/tests/ui/elif.stderr deleted file mode 100644 index 593e5c4e..00000000 --- a/testing/tests/ui/elif.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error: unknown `elif` keyword; did you mean `else if`? - failed to parse template source at row 1, column 16 near: - "elif false %}{% endif %}" - --> tests/ui/elif.rs:3:10 - | -3 | #[derive(Template)] - | ^^^^^^^^ - | - = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)