From 786d132c1deb295b1fc77441d85201b556685b82 Mon Sep 17 00:00:00 2001 From: progmboy Date: Tue, 16 Jan 2024 17:39:49 +0800 Subject: [PATCH] add else chain support --- src/grammar.pest | 6 +- src/grammar.rs | 1 + src/helpers/helper_if.rs | 36 +++++++++++ src/render.rs | 6 ++ src/template.rs | 135 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 174 insertions(+), 10 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index ac6776ee2..235dd884b 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -53,7 +53,7 @@ subexpression = { "(" ~ ((identifier ~ (hash|param)+) | reference) ~ ")" } pre_whitespace_omitter = { "~" } pro_whitespace_omitter = { "~" } -expression = { !invert_tag ~ "{{" ~ pre_whitespace_omitter? ~ +expression = { !(invert_tag|invert_chain_tag) ~ "{{" ~ pre_whitespace_omitter? ~ ((identifier ~ (hash|param)+) | name ) ~ pro_whitespace_omitter? ~ "}}" } html_expression_triple_bracket_legacy = _{ "{{{" ~ pre_whitespace_omitter? ~ @@ -76,12 +76,14 @@ partial_expression = { "{{" ~ pre_whitespace_omitter? ~ ">" ~ partial_exp_line invert_tag_item = { "else"|"^" } invert_tag = { !escape ~ "{{" ~ pre_whitespace_omitter? ~ invert_tag_item ~ pro_whitespace_omitter? ~ "}}" } +invert_chain_tag = { !escape ~ "{{" ~ pre_whitespace_omitter? ~ invert_tag_item + ~ exp_line ~ pro_whitespace_omitter? ~ "}}" } helper_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ exp_line ~ pro_whitespace_omitter? ~ "}}" } helper_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~ pro_whitespace_omitter? ~ "}}" } helper_block = _{ helper_block_start ~ template ~ - (invert_tag ~ template)? ~ helper_block_end } + (invert_chain_tag ~ template)* ~ (invert_tag ~ template)? ~ helper_block_end } decorator_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ "*" ~ exp_line ~ pro_whitespace_omitter? ~ "}}" } diff --git a/src/grammar.rs b/src/grammar.rs index 6e61cd4e4..f58909984 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -261,6 +261,7 @@ mod test { "{{#if}}hello{{else~}}world{{/if}}", "{{#if}}hello{{~^~}}world{{/if}}", "{{#if}}{{/if}}", + "{{#if}}hello{{else if}}world{{else}}test{{/if}}" ]; for i in s.iter() { assert_rule!(Rule::helper_block, i); diff --git a/src/helpers/helper_if.rs b/src/helpers/helper_if.rs index 60aee45ee..554db45a3 100644 --- a/src/helpers/helper_if.rs +++ b/src/helpers/helper_if.rs @@ -96,6 +96,42 @@ mod test { assert_eq!(r1.unwrap(), "hello 99".to_string()); } + #[test] + fn test_if_else_chain() { + let handlebars = Registry::new(); + + assert_eq!( + "0".to_owned(), + handlebars + .render_template("{{#if a}}1{{else if b}}2{{else}}0{{/if}}", &json!({"d": 1})) + .unwrap() + ); + } + + #[test] + fn test_if_else_chain2() { + let handlebars = Registry::new(); + + assert_eq!( + "3".to_owned(), + handlebars + .render_template("{{#if a}}1{{else if b}}2{{else if c}}3{{else if d}}4{{else}}0{{/if}}", &json!({"c": 1, "d":1})) + .unwrap() + ); + } + + #[test] + fn test_if_else_chain3() { + let handlebars = Registry::new(); + + assert_eq!( + "4".to_owned(), + handlebars + .render_template("{{#if a}}1{{else if b}}2{{else if c}}3{{else if d}}4{{/if}}", &json!({"d":1})) + .unwrap() + ); + } + #[test] fn test_if_include_zero() { use std::f64; diff --git a/src/render.rs b/src/render.rs index 4216dd4e7..ba5c2cb89 100644 --- a/src/render.rs +++ b/src/render.rs @@ -665,6 +665,12 @@ impl Parameter { } } +impl Renderable for HelperTemplate { + fn render<'reg: 'rc, 'rc>(&'rc self, registry: &'reg Registry<'reg>, ctx: &'rc Context, rc: &mut RenderContext<'reg, 'rc>, out: &mut dyn Output) -> Result<(), RenderError> { + render_helper(self, registry, ctx, rc, out) + } +} + impl Renderable for Template { fn render<'reg: 'rc, 'rc>( &'rc self, diff --git a/src/template.rs b/src/template.rs index d9697b81b..eb500f2b1 100644 --- a/src/template.rs +++ b/src/template.rs @@ -62,6 +62,7 @@ impl Subexpression { inverse: None, block_param: None, block: false, + chain: false, }))), } } @@ -135,6 +136,7 @@ pub struct HelperTemplate { pub template: Option