forester_rs/runtime/rtree/
iter.rs

1use crate::runtime::rtree::rnode::{RNode, RNodeId};
2use crate::runtime::rtree::RuntimeTree;
3use std::collections::VecDeque;
4/// simple bfs iterator over the tree
5pub struct RtTreeBfsIter<'a> {
6    pub queue: VecDeque<RNodeId>,
7    pub tree: &'a RuntimeTree,
8}
9
10impl<'a> Iterator for RtTreeBfsIter<'a> {
11    type Item = (RNodeId, &'a RNode);
12
13    fn next(&mut self) -> Option<Self::Item> {
14        match self.queue.pop_front() {
15            None => None,
16            Some(id) => match self.tree.nodes.get(&id) {
17                None => None,
18                Some(node) => {
19                    match &node {
20                        RNode::Leaf(_, _) => {}
21                        RNode::Flow(_, _, _, children) => self.queue.extend(children.iter()),
22                        RNode::Decorator(_, _, child) => self.queue.push_back(*child),
23                    }
24                    Some((id, node))
25                }
26            },
27        }
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::runtime::args::RtArgs;
34    use crate::runtime::rtree::builder::RtNodeBuilder;
35    use crate::runtime::rtree::builder::RtTreeBuilder;
36    use crate::runtime::rtree::rnode::FlowType;
37    use crate::runtime::rtree::rnode::RNodeName;
38    use crate::*;
39    #[test]
40    fn smoke() {
41        let flow = flow!(fallback node_name!("main"), args!();
42            flow!(sequence node_name!("root"), args!();
43                 action!(node_name!("action1"))
44            ),
45           action!(node_name!("action2"))
46        );
47        let mut rtb = RtTreeBuilder::new();
48        rtb.add_as_root(flow);
49        let tree = rtb.build().unwrap().0;
50        let elems: Vec<_> = tree
51            .iter()
52            .map(|(id, node)| (id, node.name().unwrap().name().unwrap().clone()))
53            .collect();
54
55        assert_eq!(
56            elems,
57            vec![
58                (1, "main".to_string()),
59                (2, "root".to_string()),
60                (4, "action2".to_string()),
61                (3, "action1".to_string()),
62            ]
63        );
64    }
65}