crate::ix!();
pub fn make_general_bfs_skeleton<F>(
depth: u8,
mut decide_children: F,
final_leaf_count: u16,
) -> Skeleton
where
F: FnMut(u8, u16) -> usize
{
if depth == 0 {
return SkeletonBuilder::default().build().unwrap();
}
let mut nodes = Vec::new();
let mut queue = VecDeque::new();
let mut next_id = 0u16;
let root = SkeletonNodeBuilder::default()
.id(next_id)
.name("genRoot")
.original_key("genRoot")
.build(NodeKind::Aggregate)
.unwrap();
nodes.push(root);
queue.push_back((next_id, 0u8));
next_id += 1;
while let Some((nid, lvl)) = queue.pop_front() {
if lvl >= depth - 1 {
for node in nodes.iter_mut() {
if node.id() == nid {
node.set_leaf_count(final_leaf_count);
}
}
} else {
let ccount = decide_children(lvl, nid);
let mut cids = vec![];
for _ in 0..ccount {
let cid = next_id;
next_id += 1;
let cnode = SkeletonNodeBuilder::default()
.id(cid)
.name(format!("Node{}", cid))
.original_key(format!("Node{}", cid))
.build(NodeKind::Dispatch)
.unwrap();
nodes.push(cnode);
cids.push(cid);
queue.push_back((cid, lvl+1));
}
for nd in nodes.iter_mut() {
if nd.id() == nid {
nd.set_child_ids(cids);
break;
}
}
}
}
SkeletonBuilder::default()
.nodes(nodes)
.root_id(Some(0))
.build()
.unwrap()
}