Skip to main content

cursive_tree/model/
iterator.rs

1use super::{super::backend::*, list::*, node::*};
2
3//
4// NodeIterator
5//
6
7/// Tree node iterator.
8///
9/// Iterates the nodes in visual order from top to bottom.
10pub struct NodeIterator<'model, BackendT>
11where
12    BackendT: TreeBackend,
13{
14    current_node_list: &'model NodeList<BackendT>,
15    next_index: usize,
16    only_expanded: bool,
17    stack: Vec<(&'model NodeList<BackendT>, usize)>,
18}
19
20impl<'model, BackendT> NodeIterator<'model, BackendT>
21where
22    BackendT: TreeBackend,
23{
24    /// Constructor.
25    ///
26    /// When only_expanded is true will skip the children of collapsed branches.
27    pub fn new(roots: &'model NodeList<BackendT>, only_expanded: bool) -> Self {
28        Self { current_node_list: roots, next_index: 0, only_expanded, stack: Default::default() }
29    }
30}
31
32impl<'model, BackendT> Iterator for NodeIterator<'model, BackendT>
33where
34    BackendT: TreeBackend,
35{
36    type Item = &'model Node<BackendT>;
37
38    fn next(&mut self) -> Option<Self::Item> {
39        match self.current_node_list.0.get(self.next_index) {
40            Some(node) => {
41                self.next_index += 1;
42
43                if node.kind.is_branch()
44                    && (!self.only_expanded || node.branch_state.is_expanded())
45                    && let Some(children) = &node.children
46                {
47                    // Remember our place for later
48                    self.stack.push((self.current_node_list, self.next_index));
49
50                    // Continue into children
51                    self.current_node_list = children;
52                    self.next_index = 0;
53                }
54
55                Some(node)
56            }
57
58            None => match self.stack.pop() {
59                Some((current_nodes, next_index)) => {
60                    // Go back to where we were before
61                    self.current_node_list = current_nodes;
62                    self.next_index = next_index;
63                    self.next()
64                }
65
66                None => None,
67            },
68        }
69    }
70}