]>
Commit | Line | Data |
---|---|---|
8bb4bdeb XL |
1 | use serde_json::value::Value as Json; |
2 | ||
3 | use helpers::HelperDef; | |
4 | use registry::Registry; | |
5 | use context::JsonRender; | |
6 | use render::{RenderContext, RenderError, Helper}; | |
7 | ||
8 | #[derive(Clone, Copy)] | |
9 | pub struct LookupHelper; | |
10 | ||
11 | impl HelperDef for LookupHelper { | |
12 | fn call(&self, h: &Helper, _: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> { | |
13 | let collection_value = try!(h.param(0).ok_or_else(|| { | |
14 | RenderError::new("Param not found for helper \"lookup\"") | |
15 | })); | |
16 | let index = try!(h.param(1).ok_or_else(|| { | |
17 | RenderError::new("Insufficient params for helper \"lookup\"") | |
18 | })); | |
19 | ||
20 | let null = Json::Null; | |
21 | let value = match collection_value.value() { | |
22 | &Json::Array(ref v) => { | |
23 | index.value() | |
7cac9316 XL |
24 | .as_u64() |
25 | .and_then(|u| Some(u as usize)) | |
26 | .and_then(|u| v.get(u)) | |
27 | .unwrap_or(&null) | |
8bb4bdeb | 28 | } |
8bb4bdeb XL |
29 | &Json::Object(ref m) => { |
30 | index.value() | |
7cac9316 XL |
31 | .as_str() |
32 | .and_then(|k| m.get(k)) | |
33 | .unwrap_or(&null) | |
8bb4bdeb XL |
34 | } |
35 | _ => &null, | |
36 | }; | |
37 | let r = value.render(); | |
38 | try!(rc.writer.write(r.into_bytes().as_ref())); | |
39 | Ok(()) | |
40 | } | |
41 | } | |
42 | ||
43 | pub static LOOKUP_HELPER: LookupHelper = LookupHelper; | |
44 | ||
45 | #[cfg(test)] | |
46 | mod test { | |
47 | use registry::Registry; | |
48 | ||
49 | use std::collections::BTreeMap; | |
50 | ||
51 | #[test] | |
52 | fn test_lookup() { | |
53 | let mut handlebars = Registry::new(); | |
54 | assert!(handlebars.register_template_string("t0", "{{#each v1}}{{lookup ../../v2 @index}}{{/each}}").is_ok()); | |
55 | assert!(handlebars.register_template_string("t1", | |
56 | "{{#each v1}}{{lookup ../../v2 1}}{{/each}}") | |
7cac9316 | 57 | .is_ok()); |
8bb4bdeb XL |
58 | assert!(handlebars.register_template_string("t2", "{{lookup kk \"a\"}}").is_ok()); |
59 | ||
60 | let mut m: BTreeMap<String, Vec<u16>> = BTreeMap::new(); | |
61 | m.insert("v1".to_string(), vec![1u16, 2u16, 3u16]); | |
62 | m.insert("v2".to_string(), vec![9u16, 8u16, 7u16]); | |
63 | ||
64 | let m2 = btreemap!{ | |
65 | "kk".to_string() => btreemap!{"a".to_string() => "world".to_string()} | |
66 | }; | |
67 | ||
68 | let r0 = handlebars.render("t0", &m); | |
69 | assert_eq!(r0.ok().unwrap(), "987".to_string()); | |
70 | ||
71 | let r1 = handlebars.render("t1", &m); | |
72 | assert_eq!(r1.ok().unwrap(), "888".to_string()); | |
73 | ||
74 | let r2 = handlebars.render("t2", &m2); | |
75 | assert_eq!(r2.ok().unwrap(), "world".to_string()); | |
76 | } | |
77 | } |