handbar 0.0.5

Fork of Handlebars.
use crate::context::Context;
use crate::error::RenderError;
use crate::helpers::{HelperDef, HelperResult};
use crate::output::Output;
use crate::registry::Registry;
use crate::render::{Helper, RenderContext};
use crate::Renderable;

#[derive(Clone, Copy)]
pub struct VarHelper;

impl HelperDef for VarHelper {
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> HelperResult {
        let name = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"var\": name"))?
            .value()
            .as_str()
            .ok_or_else(|| {
                RenderError::new("Param invalid for helper \"var\": name must be string")
            })?;

        let value = h
            .param(1)
            .ok_or_else(|| RenderError::new("Param not found for helper \"var\": value"))?
            .value();

        let block = rc
            .block_mut()
            .ok_or_else(|| RenderError::new("Filed to get block for helper \"var\""))?;

        block.set_local_var(name, value.to_owned());

        if let Some(t) = h.template() {
            t.render(r, ctx, rc, out)?;
        };
        Ok(())
    }
}

pub static VAR_HELPER: VarHelper = VarHelper;

#[cfg(test)]
mod test {
    #[test]
    fn test_var() {
        assert_renders![
            (r##"{{var "foo" "{}"}}"##, r##""##),
            (r##"{{var "foo" "{}"}}{{ @foo }}"##, r##"{}"##),
            (r##"{{var "foo" {}}}{{ @foo }}"##, r##"[object]"##),
            (
                r##"{{ var "foo" {"bar": 33} }}{{ @foo }}"##,
                r##"[object]"##,
            ),
            (
                r##"{{ var "foo" "hello world"}}{{ @foo }}"##,
                r##"hello world"##,
            ),
            (
                r##"{{ var "foo" "1" }}{{ var "foo" "2" }}{{ @foo }}"##,
                r##"2"##,
            ),
            (
                r##"{{var "foo" "test"}}{{#ctx @foo}}{{this}}{{/ctx}}"##,
                r##"test"##,
            ),
            (
                r##"{{var "foo" "test"}}{{#ctx @foo}}{{var "bar" 1}}{{/ctx}}{{@bar}}"##,
                r##""##,
            ),
        ];
    }
}