summaryrefslogtreecommitdiffstats
path: root/vendor/handlebars/src/helpers/helper_with.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/handlebars/src/helpers/helper_with.rs')
-rw-r--r--vendor/handlebars/src/helpers/helper_with.rs276
1 files changed, 276 insertions, 0 deletions
diff --git a/vendor/handlebars/src/helpers/helper_with.rs b/vendor/handlebars/src/helpers/helper_with.rs
new file mode 100644
index 000000000..c4d31cd0e
--- /dev/null
+++ b/vendor/handlebars/src/helpers/helper_with.rs
@@ -0,0 +1,276 @@
+use super::block_util::create_block;
+use crate::block::BlockParams;
+use crate::context::Context;
+use crate::error::RenderError;
+use crate::helpers::{HelperDef, HelperResult};
+use crate::json::value::JsonTruthy;
+use crate::output::Output;
+use crate::registry::Registry;
+use crate::render::{Helper, RenderContext, Renderable};
+
+#[derive(Clone, Copy)]
+pub struct WithHelper;
+
+impl HelperDef for WithHelper {
+ fn call<'reg: 'rc, 'rc>(
+ &self,
+ h: &Helper<'reg, 'rc>,
+ r: &'reg Registry<'reg>,
+ ctx: &'rc Context,
+ rc: &mut RenderContext<'reg, 'rc>,
+ out: &mut dyn Output,
+ ) -> HelperResult {
+ let param = h
+ .param(0)
+ .ok_or_else(|| RenderError::new("Param not found for helper \"with\""))?;
+
+ if param.value().is_truthy(false) {
+ let mut block = create_block(&param);
+
+ if let Some(block_param) = h.block_param() {
+ let mut params = BlockParams::new();
+ if param.context_path().is_some() {
+ params.add_path(block_param, Vec::with_capacity(0))?;
+ } else {
+ params.add_value(block_param, param.value().clone())?;
+ }
+
+ block.set_block_params(params);
+ }
+
+ rc.push_block(block);
+
+ if let Some(t) = h.template() {
+ t.render(r, ctx, rc, out)?;
+ };
+
+ rc.pop_block();
+ Ok(())
+ } else if let Some(t) = h.inverse() {
+ t.render(r, ctx, rc, out)
+ } else if r.strict_mode() {
+ Err(RenderError::strict_error(param.relative_path()))
+ } else {
+ Ok(())
+ }
+ }
+}
+
+pub static WITH_HELPER: WithHelper = WithHelper;
+
+#[cfg(test)]
+mod test {
+ use crate::json::value::to_json;
+ use crate::registry::Registry;
+
+ #[derive(Serialize)]
+ struct Address {
+ city: String,
+ country: String,
+ }
+
+ #[derive(Serialize)]
+ struct Person {
+ name: String,
+ age: i16,
+ addr: Address,
+ titles: Vec<String>,
+ }
+
+ #[test]
+ fn test_with() {
+ let addr = Address {
+ city: "Beijing".to_string(),
+ country: "China".to_string(),
+ };
+
+ let person = Person {
+ name: "Ning Sun".to_string(),
+ age: 27,
+ addr,
+ titles: vec!["programmer".to_string(), "cartographier".to_string()],
+ };
+
+ let mut handlebars = Registry::new();
+ assert!(handlebars
+ .register_template_string("t0", "{{#with addr}}{{city}}{{/with}}")
+ .is_ok());
+ assert!(handlebars
+ .register_template_string("t1", "{{#with notfound}}hello{{else}}world{{/with}}")
+ .is_ok());
+ assert!(handlebars
+ .register_template_string("t2", "{{#with addr/country}}{{this}}{{/with}}")
+ .is_ok());
+
+ let r0 = handlebars.render("t0", &person);
+ assert_eq!(r0.ok().unwrap(), "Beijing".to_string());
+
+ let r1 = handlebars.render("t1", &person);
+ assert_eq!(r1.ok().unwrap(), "world".to_string());
+
+ let r2 = handlebars.render("t2", &person);
+ assert_eq!(r2.ok().unwrap(), "China".to_string());
+ }
+
+ #[test]
+ fn test_with_block_param() {
+ let addr = Address {
+ city: "Beijing".to_string(),
+ country: "China".to_string(),
+ };
+
+ let person = Person {
+ name: "Ning Sun".to_string(),
+ age: 27,
+ addr,
+ titles: vec!["programmer".to_string(), "cartographier".to_string()],
+ };
+
+ let mut handlebars = Registry::new();
+ assert!(handlebars
+ .register_template_string("t0", "{{#with addr as |a|}}{{a.city}}{{/with}}")
+ .is_ok());
+ assert!(handlebars
+ .register_template_string("t1", "{{#with notfound as |c|}}hello{{else}}world{{/with}}")
+ .is_ok());
+ assert!(handlebars
+ .register_template_string("t2", "{{#with addr/country as |t|}}{{t}}{{/with}}")
+ .is_ok());
+
+ let r0 = handlebars.render("t0", &person);
+ assert_eq!(r0.ok().unwrap(), "Beijing".to_string());
+
+ let r1 = handlebars.render("t1", &person);
+ assert_eq!(r1.ok().unwrap(), "world".to_string());
+
+ let r2 = handlebars.render("t2", &person);
+ assert_eq!(r2.ok().unwrap(), "China".to_string());
+ }
+
+ #[test]
+ fn test_with_in_each() {
+ let addr = Address {
+ city: "Beijing".to_string(),
+ country: "China".to_string(),
+ };
+
+ let person = Person {
+ name: "Ning Sun".to_string(),
+ age: 27,
+ addr,
+ titles: vec!["programmer".to_string(), "cartographier".to_string()],
+ };
+
+ let addr2 = Address {
+ city: "Beijing".to_string(),
+ country: "China".to_string(),
+ };
+
+ let person2 = Person {
+ name: "Ning Sun".to_string(),
+ age: 27,
+ addr: addr2,
+ titles: vec!["programmer".to_string(), "cartographier".to_string()],
+ };
+
+ let people = vec![person, person2];
+
+ let mut handlebars = Registry::new();
+ assert!(handlebars
+ .register_template_string(
+ "t0",
+ "{{#each this}}{{#with addr}}{{city}}{{/with}}{{/each}}"
+ )
+ .is_ok());
+ assert!(handlebars
+ .register_template_string(
+ "t1",
+ "{{#each this}}{{#with addr}}{{../age}}{{/with}}{{/each}}"
+ )
+ .is_ok());
+ assert!(handlebars
+ .register_template_string(
+ "t2",
+ "{{#each this}}{{#with addr}}{{@../index}}{{/with}}{{/each}}"
+ )
+ .is_ok());
+
+ let r0 = handlebars.render("t0", &people);
+ assert_eq!(r0.ok().unwrap(), "BeijingBeijing".to_string());
+
+ let r1 = handlebars.render("t1", &people);
+ assert_eq!(r1.ok().unwrap(), "2727".to_string());
+
+ let r2 = handlebars.render("t2", &people);
+ assert_eq!(r2.ok().unwrap(), "01".to_string());
+ }
+
+ #[test]
+ fn test_path_up() {
+ let mut handlebars = Registry::new();
+ assert!(handlebars
+ .register_template_string("t0", "{{#with a}}{{#with b}}{{../../d}}{{/with}}{{/with}}")
+ .is_ok());
+ let data = btreemap! {
+ "a".to_string() => to_json(&btreemap! {
+ "b".to_string() => vec![btreemap!{"c".to_string() => vec![1]}]
+ }),
+ "d".to_string() => to_json(1)
+ };
+
+ let r0 = handlebars.render("t0", &data);
+ assert_eq!(r0.ok().unwrap(), "1".to_string());
+ }
+
+ #[test]
+ fn test_else_context() {
+ let reg = Registry::new();
+ let template = "{{#with list}}A{{else}}{{foo}}{{/with}}";
+ let input = json!({"list": [], "foo": "bar"});
+ let rendered = reg.render_template(template, &input).unwrap();
+ assert_eq!("bar", rendered);
+ }
+
+ #[test]
+ fn test_derived_value() {
+ let hb = Registry::new();
+ let data = json!({"a": {"b": {"c": "d"}}});
+ let template = "{{#with (lookup a.b \"c\")}}{{this}}{{/with}}";
+ assert_eq!("d", hb.render_template(template, &data).unwrap());
+ }
+
+ #[test]
+ fn test_nested_derived_value() {
+ let hb = Registry::new();
+ let data = json!({"a": {"b": {"c": "d"}}});
+ let template = "{{#with (lookup a \"b\")}}{{#with this}}{{c}}{{/with}}{{/with}}";
+ assert_eq!("d", hb.render_template(template, &data).unwrap());
+ }
+
+ #[test]
+ fn test_strict_with() {
+ let mut hb = Registry::new();
+
+ assert_eq!(
+ hb.render_template("{{#with name}}yes{{/with}}", &json!({}))
+ .unwrap(),
+ ""
+ );
+ assert_eq!(
+ hb.render_template("{{#with name}}yes{{else}}no{{/with}}", &json!({}))
+ .unwrap(),
+ "no"
+ );
+
+ hb.set_strict_mode(true);
+
+ assert!(hb
+ .render_template("{{#with name}}yes{{/with}}", &json!({}))
+ .is_err());
+ assert_eq!(
+ hb.render_template("{{#with name}}yes{{else}}no{{/with}}", &json!({}))
+ .unwrap(),
+ "no"
+ );
+ }
+}