Skip to main content

cursive_tree/model/
list.rs

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