use serde_json::value::Value as Json;
use crate::context::Context;
use crate::error::RenderError;
use crate::helpers::HelperDef;
use crate::json::value::ScopedJson;
use crate::registry::Registry;
use crate::render::{Helper, RenderContext};
type ArrayInsertionFn = fn(Vec<Json>, Json) -> Vec<Json>;
#[derive(Clone, Copy)]
pub struct ArrayInsertionHelper {
name: crate::HelperName,
op: ArrayInsertionFn,
}
impl HelperDef for ArrayInsertionHelper {
fn call_inner<'reg: 'rc, 'rc>(
&self,
h: &Helper<'rc>,
_: &'reg Registry<'reg>,
_: &'rc Context,
_: &mut RenderContext<'reg, 'rc>,
) -> Result<ScopedJson<'rc>, RenderError> {
let list = h
.param(0)
.ok_or_else(|| {
RenderError::new(format!(
"Param not found for helper \"{}\": list",
self.name
))
})?
.value()
.as_array()
.ok_or_else(|| {
RenderError::new(format!(
"Param invalid for helper \"{}\": list must be array",
self.name
))
})?;
let value = h
.param(1)
.ok_or_else(|| {
RenderError::new(format!(
"Param not found for helper \"{}\": value",
self.name
))
})?
.value();
let list = (self.op)(list.clone(), value.clone());
Ok(Json::Array(list).into())
}
}
pub static APPEND_HELPER: ArrayInsertionHelper = ArrayInsertionHelper {
name: crate::HelperName::Append,
op: |mut list: Vec<Json>, elem: Json| -> Vec<Json> {
list.push(elem);
list
},
};
pub static PREPEND_HELPER: ArrayInsertionHelper = ArrayInsertionHelper {
name: crate::HelperName::Append,
op: |mut list: Vec<Json>, elem: Json| -> Vec<Json> {
list.insert(0, elem);
list
},
};
#[cfg(test)]
mod test {
#[test]
fn test_append() {
assert_renders![(r##"{{ json (append [0, 1] 2) }}"##, r##"[0,1,2]"##)];
}
#[test]
fn test_prepend() {
assert_renders![(r##"{{ json (prepend [0, 1] -1) }}"##, r##"[-1,0,1]"##)];
}
}