]> git.proxmox.com Git - rustc.git/blob - src/vendor/handlebars/src/helpers/helper_with.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / vendor / handlebars / src / helpers / helper_with.rs
1 use std::collections::BTreeMap;
2
3 use helpers::HelperDef;
4 use registry::Registry;
5 use context::{JsonTruthy, to_json};
6 use render::{Renderable, RenderContext, RenderError, Helper};
7
8 #[derive(Clone, Copy)]
9 pub struct WithHelper;
10
11 impl HelperDef for WithHelper {
12 fn call(&self, h: &Helper, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> {
13 let param =
14 try!(h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"with\"")));
15
16 rc.promote_local_vars();
17
18 let result = {
19 let mut local_rc = rc.derive();
20
21 let not_empty = param.value().is_truthy();
22 let template = if not_empty { h.template() } else { h.inverse() };
23
24 if let Some(path_root) = param.path_root() {
25 let local_path_root = format!("{}/{}", local_rc.get_path(), path_root);
26 local_rc.push_local_path_root(local_path_root);
27 }
28 if not_empty {
29 if let Some(inner_path) = param.path() {
30 let new_path = format!("{}/{}", local_rc.get_path(), inner_path);
31 local_rc.set_path(new_path);
32 }
33
34 if let Some(block_param) = h.block_param() {
35 let mut map = BTreeMap::new();
36 map.insert(block_param.to_string(), to_json(param.value()));
37 local_rc.push_block_context(&map);
38 }
39 }
40
41 let result = match template {
42 Some(t) => t.render(r, &mut local_rc),
43 None => Ok(()),
44 };
45
46 if h.block_param().is_some() {
47 local_rc.pop_block_context();
48 }
49
50 if param.path_root().is_some() {
51 local_rc.pop_local_path_root();
52 }
53
54 result
55 };
56
57 rc.demote_local_vars();
58 result
59 }
60 }
61
62 pub static WITH_HELPER: WithHelper = WithHelper;
63
64 #[cfg(test)]
65 mod test {
66 use registry::Registry;
67 use context::to_json;
68
69 #[derive(Serialize)]
70 struct Address {
71 city: String,
72 country: String,
73 }
74
75 #[derive(Serialize)]
76 struct Person {
77 name: String,
78 age: i16,
79 addr: Address,
80 titles: Vec<String>,
81 }
82
83 #[test]
84 fn test_with() {
85 let addr = Address {
86 city: "Beijing".to_string(),
87 country: "China".to_string(),
88 };
89
90 let person = Person {
91 name: "Ning Sun".to_string(),
92 age: 27,
93 addr: addr,
94 titles: vec!["programmer".to_string(), "cartographier".to_string()],
95 };
96
97 let mut handlebars = Registry::new();
98 assert!(handlebars.register_template_string("t0", "{{#with addr}}{{city}}{{/with}}")
99 .is_ok());
100 assert!(handlebars.register_template_string("t1",
101 "{{#with notfound}}hello{{else}}world{{/with}}")
102 .is_ok());
103 assert!(handlebars.register_template_string("t2",
104 "{{#with addr/country}}{{this}}{{/with}}")
105 .is_ok());
106
107 let r0 = handlebars.render("t0", &person);
108 assert_eq!(r0.ok().unwrap(), "Beijing".to_string());
109
110 let r1 = handlebars.render("t1", &person);
111 assert_eq!(r1.ok().unwrap(), "world".to_string());
112
113 let r2 = handlebars.render("t2", &person);
114 assert_eq!(r2.ok().unwrap(), "China".to_string());
115 }
116
117 #[test]
118 fn test_with_block_param() {
119 let addr = Address {
120 city: "Beijing".to_string(),
121 country: "China".to_string(),
122 };
123
124 let person = Person {
125 name: "Ning Sun".to_string(),
126 age: 27,
127 addr: addr,
128 titles: vec!["programmer".to_string(), "cartographier".to_string()],
129 };
130
131 let mut handlebars = Registry::new();
132 assert!(handlebars.register_template_string("t0",
133 "{{#with addr as |a|}}{{a.city}}{{/with}}")
134 .is_ok());
135 assert!(handlebars.register_template_string("t1", "{{#with notfound as |c|}}hello{{else}}world{{/with}}").is_ok());
136 assert!(handlebars.register_template_string("t2",
137 "{{#with addr/country as |t|}}{{t}}{{/with}}")
138 .is_ok());
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,
160 addr: addr,
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();
179 assert!(handlebars.register_template_string("t0", "{{#each this}}{{#with addr}}{{city}}{{/with}}{{/each}}").is_ok());
180 assert!(handlebars.register_template_string("t1", "{{#each this}}{{#with addr}}{{../age}}{{/with}}{{/each}}").is_ok());
181 assert!(handlebars.register_template_string("t2", "{{#each this}}{{#with addr}}{{@../index}}{{/with}}{{/each}}").is_ok());
182
183 let r0 = handlebars.render("t0", &people);
184 assert_eq!(r0.ok().unwrap(), "BeijingBeijing".to_string());
185
186 let r1 = handlebars.render("t1", &people);
187 assert_eq!(r1.ok().unwrap(), "2727".to_string());
188
189 let r2 = handlebars.render("t2", &people);
190 assert_eq!(r2.ok().unwrap(), "01".to_string());
191 }
192
193 #[test]
194 fn test_path_up() {
195 let mut handlebars = Registry::new();
196 assert!(handlebars.register_template_string("t0",
197 "{{#with a}}{{#with b}}{{../../d}}{{/with}}{{/with}}")
198 .is_ok());
199 let data = btreemap! {
200 "a".to_string() => to_json(&btreemap! {
201 "b".to_string() => vec![btreemap!{"c".to_string() => vec![1]}]
202 }),
203 "d".to_string() => to_json(&1)
204 };
205
206 let r0 = handlebars.render("t0", &data);
207 assert_eq!(r0.ok().unwrap(), "1".to_string());
208
209 }
210 }