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