use std::{collections::HashMap, hash::Hash};
use refutil::revref::RevMut;
enum Tree<K: Eq + Hash, V> {
Node(HashMap<K, Tree<K, V>>),
Leaf(V),
}
impl<K: Eq + Hash, V> Tree<K, V> {
pub fn traverse(&self, mut cons: impl FnMut(&[&K], &V) -> ()) {
let mut vec = Vec::new();
self.traverse_core(RevMut::new(&mut vec), &mut cons);
}
fn traverse_core<'a>(
&'a self,
mut path: RevMut<&mut Vec<&'a K>>,
cons: &mut impl FnMut(&[&K], &V) -> (),
) {
match self {
Tree::Node(children) => {
for (name, child) in children {
path.push(name);
child.traverse_core(RevMut::new(&mut path), cons);
path.pop();
}
}
Tree::Leaf(data) => cons(&path, data),
}
}
}
#[test]
fn walk_tree() {
use map::map;
let tree = Tree::Node(map!(
"a" => Tree::Node(map![
"x" => Tree::Leaf(2),
"y" => Tree::Node(map![
"i" => Tree::Leaf(4),
"j" => Tree::Leaf(5),
]),
"z" => Tree::Leaf(3)
]),
"b" => Tree::Leaf(1)
));
tree.traverse(|_path, _item| {});
}