handbar 0.0.4

Fork of Handlebars.
use crate::error::RenderError;
use crate::helpers::error::render_fmt_message;
use crate::helpers::{Context, Helper, HelperDef, RenderContext, ScopedJson};
use crate::json::value::JsonTruthy;
use crate::registry::Registry;
use serde_json::Value as Json;

#[derive(Clone, Copy)]
pub struct ErrorConditionHelper {
    name: crate::HelperName,
    positive: bool,
}

impl HelperDef for ErrorConditionHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'rc>,
        _: &'reg Registry<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'rc>, RenderError> {
        let condition = h.param(0).ok_or_else(|| {
            RenderError::new(format!(
                "Param not found for helper \"{}\": condition",
                self.name
            ))
        })?;
        let include_zero = h
            .hash_get("include_zero")
            .and_then(|v| v.value().as_bool())
            .unwrap_or(false);

        let mut condition = condition.value().is_truthy(include_zero);

        if !self.positive {
            condition = !condition;
        }

        let message = h
            .param(1)
            .ok_or_else(|| {
                RenderError::new(format!(
                    "Param not found for helper \"{}\": message",
                    self.name
                ))
            })?
            .value()
            .as_str()
            .ok_or_else(|| {
                RenderError::new(format!(
                    "Param invalid for helper \"{}\": message must be string",
                    self.name
                ))
            })?
            .to_string();

        if condition {
            return Err(RenderError::new(render_fmt_message(
                message,
                &h.params()[1..],
            )));
        }

        return Ok(Json::Null.into());
    }
}

pub static ERROR_IF_HELPER: ErrorConditionHelper = ErrorConditionHelper {
    name: crate::HelperName::ErrorIf,
    positive: true,
};

pub static ERROR_UNLESS_HELPER: ErrorConditionHelper = ErrorConditionHelper {
    name: crate::HelperName::ErrorUnless,
    positive: false,
};