]> git.proxmox.com Git - rustc.git/blame - vendor/handlebars/src/helpers/helper_with.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / vendor / handlebars / src / helpers / helper_with.rs
CommitLineData
3dfed10e
XL
1use super::block_util::create_block;
2use crate::block::BlockParams;
f9f354fc 3use crate::context::Context;
416331ca
XL
4use crate::error::RenderError;
5use crate::helpers::{HelperDef, HelperResult};
f9f354fc 6use crate::json::value::JsonTruthy;
416331ca
XL
7use crate::output::Output;
8use crate::registry::Registry;
9use crate::render::{Helper, RenderContext, Renderable};
8bb4bdeb
XL
10
11#[derive(Clone, Copy)]
12pub struct WithHelper;
13
14impl HelperDef for WithHelper {
9fa01778
XL
15 fn call<'reg: 'rc, 'rc>(
16 &self,
f9f354fc 17 h: &Helper<'reg, 'rc>,
3dfed10e 18 r: &'reg Registry<'reg>,
f9f354fc
XL
19 ctx: &'rc Context,
20 rc: &mut RenderContext<'reg, 'rc>,
416331ca 21 out: &mut dyn Output,
9fa01778
XL
22 ) -> HelperResult {
23 let param = h
24 .param(0)
25 .ok_or_else(|| RenderError::new("Param not found for helper \"with\""))?;
8bb4bdeb 26
94222f64
XL
27 if param.value().is_truthy(false) {
28 let mut block = create_block(&param);
416331ca 29
f9f354fc
XL
30 if let Some(block_param) = h.block_param() {
31 let mut params = BlockParams::new();
3dfed10e 32 if param.context_path().is_some() {
f9f354fc
XL
33 params.add_path(block_param, Vec::with_capacity(0))?;
34 } else {
35 params.add_value(block_param, param.value().clone())?;
8bb4bdeb 36 }
8bb4bdeb 37
f9f354fc 38 block.set_block_params(params);
8bb4bdeb
XL
39 }
40
f9f354fc 41 rc.push_block(block);
8bb4bdeb 42
94222f64
XL
43 if let Some(t) = h.template() {
44 t.render(r, ctx, rc, out)?;
45 };
8bb4bdeb 46
f9f354fc 47 rc.pop_block();
94222f64
XL
48 Ok(())
49 } else if let Some(t) = h.inverse() {
50 t.render(r, ctx, rc, out)
51 } else if r.strict_mode() {
52 Err(RenderError::strict_error(param.relative_path()))
53 } else {
54 Ok(())
f9f354fc 55 }
8bb4bdeb
XL
56 }
57}
58
59pub static WITH_HELPER: WithHelper = WithHelper;
60
61#[cfg(test)]
8bb4bdeb 62mod test {
f9f354fc 63 use crate::json::value::to_json;
416331ca 64 use crate::registry::Registry;
8bb4bdeb 65
041b39d2 66 #[derive(Serialize)]
8bb4bdeb
XL
67 struct Address {
68 city: String,
69 country: String,
70 }
71
041b39d2 72 #[derive(Serialize)]
8bb4bdeb
XL
73 struct Person {
74 name: String,
75 age: i16,
76 addr: Address,
77 titles: Vec<String>,
78 }
79
8bb4bdeb
XL
80 #[test]
81 fn test_with() {
82 let addr = Address {
83 city: "Beijing".to_string(),
84 country: "China".to_string(),
85 };
86
87 let person = Person {
88 name: "Ning Sun".to_string(),
89 age: 27,
416331ca 90 addr,
8bb4bdeb
XL
91 titles: vec!["programmer".to_string(), "cartographier".to_string()],
92 };
93
94 let mut handlebars = Registry::new();
416331ca
XL
95 assert!(handlebars
96 .register_template_string("t0", "{{#with addr}}{{city}}{{/with}}")
97 .is_ok());
98 assert!(handlebars
99 .register_template_string("t1", "{{#with notfound}}hello{{else}}world{{/with}}")
100 .is_ok());
101 assert!(handlebars
102 .register_template_string("t2", "{{#with addr/country}}{{this}}{{/with}}")
103 .is_ok());
8bb4bdeb
XL
104
105 let r0 = handlebars.render("t0", &person);
106 assert_eq!(r0.ok().unwrap(), "Beijing".to_string());
107
108 let r1 = handlebars.render("t1", &person);
109 assert_eq!(r1.ok().unwrap(), "world".to_string());
110
111 let r2 = handlebars.render("t2", &person);
112 assert_eq!(r2.ok().unwrap(), "China".to_string());
113 }
114
115 #[test]
116 fn test_with_block_param() {
117 let addr = Address {
118 city: "Beijing".to_string(),
119 country: "China".to_string(),
120 };
121
122 let person = Person {
123 name: "Ning Sun".to_string(),
124 age: 27,
416331ca 125 addr,
8bb4bdeb
XL
126 titles: vec!["programmer".to_string(), "cartographier".to_string()],
127 };
128
129 let mut handlebars = Registry::new();
416331ca
XL
130 assert!(handlebars
131 .register_template_string("t0", "{{#with addr as |a|}}{{a.city}}{{/with}}")
132 .is_ok());
133 assert!(handlebars
134 .register_template_string("t1", "{{#with notfound as |c|}}hello{{else}}world{{/with}}")
135 .is_ok());
136 assert!(handlebars
137 .register_template_string("t2", "{{#with addr/country as |t|}}{{t}}{{/with}}")
138 .is_ok());
8bb4bdeb
XL
139
140 let r0 = handlebars.render("t0", &person);
141 assert_eq!(r0.ok().unwrap(), "Beijing".to_string());
142
143 let r1 = handlebars.render("t1", &person);
144 assert_eq!(r1.ok().unwrap(), "world".to_string());
145
146 let r2 = handlebars.render("t2", &person);
147 assert_eq!(r2.ok().unwrap(), "China".to_string());
148 }
149
150 #[test]
151 fn test_with_in_each() {
152 let addr = Address {
153 city: "Beijing".to_string(),
154 country: "China".to_string(),
155 };
156
157 let person = Person {
158 name: "Ning Sun".to_string(),
159 age: 27,
416331ca 160 addr,
8bb4bdeb
XL
161 titles: vec!["programmer".to_string(), "cartographier".to_string()],
162 };
163
164 let addr2 = Address {
165 city: "Beijing".to_string(),
166 country: "China".to_string(),
167 };
168
169 let person2 = Person {
170 name: "Ning Sun".to_string(),
171 age: 27,
172 addr: addr2,
173 titles: vec!["programmer".to_string(), "cartographier".to_string()],
174 };
175
176 let people = vec![person, person2];
177
178 let mut handlebars = Registry::new();
416331ca
XL
179 assert!(handlebars
180 .register_template_string(
181 "t0",
182 "{{#each this}}{{#with addr}}{{city}}{{/with}}{{/each}}"
183 )
184 .is_ok());
185 assert!(handlebars
186 .register_template_string(
187 "t1",
188 "{{#each this}}{{#with addr}}{{../age}}{{/with}}{{/each}}"
189 )
190 .is_ok());
191 assert!(handlebars
192 .register_template_string(
193 "t2",
194 "{{#each this}}{{#with addr}}{{@../index}}{{/with}}{{/each}}"
195 )
196 .is_ok());
8bb4bdeb
XL
197
198 let r0 = handlebars.render("t0", &people);
199 assert_eq!(r0.ok().unwrap(), "BeijingBeijing".to_string());
200
201 let r1 = handlebars.render("t1", &people);
202 assert_eq!(r1.ok().unwrap(), "2727".to_string());
203
204 let r2 = handlebars.render("t2", &people);
205 assert_eq!(r2.ok().unwrap(), "01".to_string());
206 }
207
208 #[test]
209 fn test_path_up() {
210 let mut handlebars = Registry::new();
416331ca
XL
211 assert!(handlebars
212 .register_template_string("t0", "{{#with a}}{{#with b}}{{../../d}}{{/with}}{{/with}}")
213 .is_ok());
83c7162d 214 let data = btreemap! {
8bb4bdeb
XL
215 "a".to_string() => to_json(&btreemap! {
216 "b".to_string() => vec![btreemap!{"c".to_string() => vec![1]}]
217 }),
9fa01778 218 "d".to_string() => to_json(1)
8bb4bdeb
XL
219 };
220
221 let r0 = handlebars.render("t0", &data);
222 assert_eq!(r0.ok().unwrap(), "1".to_string());
8bb4bdeb 223 }
3dfed10e
XL
224
225 #[test]
226 fn test_else_context() {
227 let reg = Registry::new();
228 let template = "{{#with list}}A{{else}}{{foo}}{{/with}}";
229 let input = json!({"list": [], "foo": "bar"});
230 let rendered = reg.render_template(template, &input).unwrap();
231 assert_eq!("bar", rendered);
232 }
233
234 #[test]
235 fn test_derived_value() {
236 let hb = Registry::new();
237 let data = json!({"a": {"b": {"c": "d"}}});
238 let template = "{{#with (lookup a.b \"c\")}}{{this}}{{/with}}";
239 assert_eq!("d", hb.render_template(template, &data).unwrap());
240 }
241
242 #[test]
243 fn test_nested_derived_value() {
244 let hb = Registry::new();
245 let data = json!({"a": {"b": {"c": "d"}}});
246 let template = "{{#with (lookup a \"b\")}}{{#with this}}{{c}}{{/with}}{{/with}}";
247 assert_eq!("d", hb.render_template(template, &data).unwrap());
248 }
94222f64
XL
249
250 #[test]
251 fn test_strict_with() {
252 let mut hb = Registry::new();
253
254 assert_eq!(
255 hb.render_template("{{#with name}}yes{{/with}}", &json!({}))
256 .unwrap(),
257 ""
258 );
259 assert_eq!(
260 hb.render_template("{{#with name}}yes{{else}}no{{/with}}", &json!({}))
261 .unwrap(),
262 "no"
263 );
264
265 hb.set_strict_mode(true);
266
267 assert!(hb
268 .render_template("{{#with name}}yes{{/with}}", &json!({}))
269 .is_err());
270 assert_eq!(
271 hb.render_template("{{#with name}}yes{{else}}no{{/with}}", &json!({}))
272 .unwrap(),
273 "no"
274 );
275 }
8bb4bdeb 276}