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 96 97 98 99 100
#![deny(unsafe_code)] use handlebars::Handlebars; use handlebars::HelperDef; use snafu::Snafu; pub mod assign_helpers; pub mod env_helpers; #[cfg(feature = "http")] pub mod http_helpers; #[cfg(feature = "json")] pub mod json_helpers; pub mod path_helpers; #[cfg(feature = "string")] pub mod string_helpers; #[derive(Debug, Snafu)] enum HelperError { #[snafu(display("missing param {} '{}' of '{}'", position, name, helper_signature))] MissingParameter { position: usize, name: String, helper_signature: String, }, } pub fn new_hbs() -> Handlebars { let mut handlebars = Handlebars::new(); setup_handlebars(&mut handlebars); handlebars } pub fn setup_handlebars(handlebars: &mut Handlebars) { handlebars.set_strict_mode(true); register(handlebars); } pub fn register(handlebars: &mut Handlebars) -> Vec<Box<dyn HelperDef + 'static>> { vec![ #[cfg(feature = "string")] string_helpers::register(handlebars), #[cfg(feature = "http")] http_helpers::register(handlebars), path_helpers::register(handlebars), env_helpers::register(handlebars), #[cfg(feature = "json")] json_helpers::register(handlebars), assign_helpers::register(handlebars), ] .into_iter() .flatten() .collect() } #[cfg(test)] mod tests { use super::*; use spectral::prelude::*; use std::collections::HashMap; use std::error::Error; pub(crate) fn assert_helpers( input: &str, helper_expected: Vec<(&str, &str)>, ) -> Result<(), Box<dyn Error>> { let mut vs: HashMap<String, String> = HashMap::new(); vs.insert("var".into(), input.into()); let hbs = new_hbs(); for sample in helper_expected { let tmpl = format!("{{{{ {} var}}}}", sample.0); assert_that!(hbs.render_template(&tmpl, &vs)?) .named(sample.0) .is_equal_to(sample.1.to_owned()); } Ok(()) } pub(crate) fn assert_renders(samples_expected: Vec<(&str, &str)>) -> Result<(), Box<dyn Error>> { let vs: HashMap<String, String> = HashMap::new(); let hbs = new_hbs(); for sample in samples_expected { let tmpl = sample.0; assert_that!(hbs.render_template(&tmpl, &vs)?) .named(sample.0) .is_equal_to(sample.1.to_owned()); } Ok(()) } #[test] #[cfg(feature = "string")] fn test_chain_of_helpers_with_1_param() -> Result<(), Box<dyn Error>> { let vs: HashMap<String, String> = HashMap::new(); let hbs = new_hbs(); let tmpl = r#"{{ to_upper_case (to_singular "Hello foo-bars")}}"#.to_owned(); let actual = hbs.render_template(&tmpl, &vs)?; assert_that!(&actual).is_equal_to("BAR".to_string()); Ok(()) } }