Skip to main content

cursive_tree/model/
list.rs

1use super::{super::backend::*, depth::*, iterator::*, kind::*, node::*, path::*, representation::*};
2
3use std::{ptr, slice::*};
4
5//
6// NodeList
7//
8
9/// Tree node list.
10pub struct NodeList<BackendT>(pub Vec<Node<BackendT>>)
11where
12    BackendT: TreeBackend;
13
14impl<BackendT> NodeList<BackendT>
15where
16    BackendT: TreeBackend,
17{
18    /// Iterate nodes in visual order from top to bottom.
19    ///
20    /// When only_expanded is true will skip the children of collapsed branches.
21    pub fn iter(&self, only_expanded: bool) -> NodeIterator<'_, BackendT> {
22        NodeIterator::new(self, only_expanded)
23    }
24
25    /// Get node at path.
26    pub fn at_path(&self, mut path: NodePath) -> Option<&Node<BackendT>> {
27        path.pop_front().and_then(|index| self.0.get(index)).and_then(|node| node.at_path(path))
28    }
29
30    /// Get node at path.
31    pub fn at_path_mut(&mut self, mut path: NodePath) -> Option<&mut Node<BackendT>> {
32        path.pop_front().and_then(|index| self.0.get_mut(index)).and_then(|node| node.at_path_mut(path))
33    }
34
35    /// Fill path to node.
36    ///
37    /// Returns true if found.
38    pub fn fill_path(&self, path: &mut NodePath, node: &Node<BackendT>) -> bool {
39        if self.0.is_empty() {
40            return false;
41        }
42
43        for (index, node_) in self.0.iter().enumerate() {
44            path.push_back(index);
45            if ptr::eq(node, node_) {
46                return true;
47            } else if node_.fill_path(path, node) {
48                return true;
49            } else {
50                path.pop_back();
51            }
52        }
53
54        false
55    }
56
57    /// Add a node.
58    pub fn add(&mut self, depth: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) {
59        self.0.push(Node::new(depth, kind, id, representation));
60    }
61
62    /// Insert a node.
63    pub fn insert(
64        &mut self,
65        index: usize,
66        depth: usize,
67        kind: NodeKind,
68        id: BackendT::ID,
69        representation: Representation,
70    ) {
71        self.0.insert(index, Node::new(depth, kind, id, representation));
72    }
73
74    /// Expand branch nodes.
75    ///
76    /// If depth is [None] will expand all depths.
77    ///
78    /// If depth is 0 will do nothing.
79    pub fn expand(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
80    where
81        BackendT::Context: Clone,
82    {
83        if depth.is_zero() {
84            return Ok(());
85        }
86
87        depth.decrease();
88
89        for node in self {
90            if node.kind.is_branch() {
91                node.expand(context.clone())?;
92
93                if !depth.is_zero()
94                    && let Some(children) = &mut node.children
95                {
96                    children.expand(depth, context.clone())?;
97                }
98            }
99        }
100
101        Ok(())
102    }
103
104    /// Collapse branch nodes.
105    ///
106    /// If depth is [None] will collapse all depths.
107    ///
108    /// If depth is 0 will do nothing.
109    pub fn collapse(&mut self, mut depth: Option<usize>) {
110        if depth.is_zero() {
111            return;
112        }
113
114        depth.decrease();
115
116        for node in self {
117            if node.kind.is_branch() {
118                node.collapse();
119
120                if !depth.is_zero()
121                    && let Some(children) = &mut node.children
122                {
123                    children.collapse(depth);
124                }
125            }
126        }
127    }
128}
129
130impl<BackendT> Default for NodeList<BackendT>
131where
132    BackendT: TreeBackend,
133{
134    fn default() -> Self {
135        Self(Default::default())
136    }
137}
138
139impl<'this, BackendT> IntoIterator for &'this NodeList<BackendT>
140where
141    BackendT: TreeBackend,
142{
143    type Item = &'this Node<BackendT>;
144    type IntoIter = Iter<'this, Node<BackendT>>;
145
146    fn into_iter(self) -> Self::IntoIter {
147        self.0.iter()
148    }
149}
150
151impl<'this, BackendT> IntoIterator for &'this mut NodeList<BackendT>
152where
153    BackendT: TreeBackend,
154{
155    type Item = &'this mut Node<BackendT>;
156    type IntoIter = IterMut<'this, Node<BackendT>>;
157
158    fn into_iter(self) -> Self::IntoIter {
159        self.0.iter_mut()
160    }
161}
162
163impl<BackendT> FromIterator<Node<BackendT>> for NodeList<BackendT>
164where
165    BackendT: TreeBackend,
166{
167    fn from_iter<IteratorT>(iterator: IteratorT) -> Self
168    where
169        IteratorT: IntoIterator<Item = Node<BackendT>>,
170    {
171        Self(Vec::from_iter(iterator))
172    }
173}
174
175impl<BackendT> From<Vec<Node<BackendT>>> for NodeList<BackendT>
176where
177    BackendT: TreeBackend,
178{
179    fn from(vector: Vec<Node<BackendT>>) -> Self {
180        Self(vector)
181    }
182}