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