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