use crate::{Group, Node, Op, Tree};
pub fn groups_filtered(
tree: &Tree,
pred: &impl Fn(&str) -> bool,
f: &mut impl FnMut(&[String], &Group),
) {
groups_filtered_recurse(tree, pred, &mut vec![], f)
}
pub fn groups_filtered_recurse(
tree: &Tree,
pred: &impl Fn(&str) -> bool,
names: &mut Vec<String>,
f: &mut impl FnMut(&[String], &Group),
) {
for (name, node) in tree.iter() {
if let Node::Group(g) = node {
if pred(name) {
names.push(name.to_string());
f(names, g);
groups_filtered_recurse(&g.tree, pred, names, f);
names.pop();
}
}
}
}
pub fn groups(tree: &Tree, f: &mut impl FnMut(&[String], &Group)) {
groups_filtered(tree, &|_| true, f)
}
pub fn ops_filtered(tree: &Tree, pred: impl Fn(&str) -> bool, f: &mut impl FnMut(&[String], &Op)) {
ops_filtered_recurse(tree, &pred, &mut vec![], f)
}
pub fn ops_filtered_recurse(
tree: &Tree,
pred: &impl Fn(&str) -> bool,
names: &mut Vec<String>,
f: &mut impl FnMut(&[String], &Op),
) {
for (name, node) in tree.iter() {
if pred(name) {
names.push(name.to_string());
match node {
Node::Group(g) => ops_filtered_recurse(&g.tree, pred, names, f),
Node::Op(op) => f(names, op),
}
names.pop();
}
}
}
pub fn ops(tree: &Tree, f: &mut impl FnMut(&[String], &Op)) {
ops_filtered(tree, |_| true, f)
}