use crate::core::eval;
use crate::core::exec::ExecOutcome;
use crate::core::Expr;
use crate::error::{Result, TemplateError};
pub struct RecurseNode {
pub expr: Option<Expr>,
#[allow(dead_code)]
pub using: Option<Expr>,
}
impl RecurseNode {
pub fn new(expr: Option<Expr>, using: Option<Expr>) -> Self {
RecurseNode { expr, using }
}
pub(crate) fn exec(&self, env: &mut crate::core::Environment) -> Result<ExecOutcome> {
let node = match &self.expr {
Some(e) => eval::eval(env, e)?,
None => env.get_current_visitor_node().ok_or_else(|| {
TemplateError::misc(
"#recurse must be given a node, or be called while visiting a node",
)
})?,
};
let children = match &node.node {
Some(n) => n.children()?,
None => Vec::new(),
};
for c in children {
env.push_visitor_node(c.clone());
let r = crate::core::visit_node::visit_node(env, &c);
env.pop_visitor_node();
r?;
}
Ok(ExecOutcome::Done)
}
}