chord-flow 0.1.21

async parallel case executor
Documentation
use handlebars::handlebars_helper;
use handlebars::{Context, Handlebars, Helper, HelperDef, RenderContext, RenderError, ScopedJson};

use chord_core::value::{from_str, Number, Value};

handlebars_helper!(CONTAINS: |x: Json, y: Json|{
    x.is_array() && x.as_array().unwrap().contains(y)
});

pub static ARR: ArrHelper = ArrHelper {};
pub static LEN: LenHelper = LenHelper {};
pub static SUB: SubHelper = SubHelper {};
pub static GET: GetHelper = GetHelper {};

#[derive(Clone, Copy)]
pub struct ArrHelper {}

impl HelperDef for ArrHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Handlebars<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        let param = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"arr\""))?;

        match param.value() {
            Value::String(txt) => Ok(ScopedJson::Derived(Value::Array(from_str(txt)?))),
            Value::Array(arr) => Ok(ScopedJson::Derived(Value::Array(arr.clone()))),
            _ => Err(RenderError::new("\"arr\" can not convert ")),
        }
    }
}

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

impl HelperDef for SubHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Handlebars<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        let params = h.params();
        let arr = params[0]
            .value()
            .as_array()
            .ok_or(RenderError::new("Param invalid for helper \"arr_sub\""))?;

        if params.len() == 2 {
            let start = params[1]
                .value()
                .as_f64()
                .ok_or(RenderError::new("Param invalid for helper \"arr_sub\""))?
                as usize;
            let mut a = Vec::<Value>::new();
            a.clone_from_slice(&arr[start..]);
            return Ok(ScopedJson::Derived(Value::Array(a)));
        } else if params.len() == 3 {
            let start = params[1]
                .value()
                .as_f64()
                .ok_or(RenderError::new("Param invalid for helper \"arr_sub\""))?
                as usize;
            let end = params[2]
                .value()
                .as_f64()
                .ok_or(RenderError::new("Param invalid for helper \"arr_sub\""))?
                as usize;
            let mut a = Vec::<Value>::new();
            a.clone_from_slice(&arr[start..end]);
            return Ok(ScopedJson::Derived(Value::Array(a)));
        } else {
            return Err(RenderError::new("Param invalid for helper \"arr_sub\""));
        }
    }
}

#[derive(Clone, Copy)]
pub struct LenHelper {}

impl HelperDef for LenHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Handlebars<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        let params = h.params();
        let arr = params[0]
            .value()
            .as_array()
            .ok_or(RenderError::new("Param invalid for helper \"arr_len\""))?;

        Ok(ScopedJson::Derived(Value::Number(Number::from(arr.len()))))
    }
}

#[derive(Clone, Copy)]
pub struct GetHelper {}

impl HelperDef for GetHelper {
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Handlebars<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        let params = h.params();
        let arr = params[0]
            .value()
            .as_array()
            .ok_or(RenderError::new("Param invalid for helper \"arr_get\""))?;

        if params.len() == 2 {
            let start = params[1]
                .value()
                .as_f64()
                .ok_or(RenderError::new("Param invalid for helper \"arr_get\""))?
                as usize;
            let result = if arr.len() > 0 {
                arr[start].clone()
            } else {
                Value::Null
            };
            return Ok(ScopedJson::Derived(result));
        } else {
            return Err(RenderError::new("Param invalid for helper \"arr_get\""));
        }
    }
}