1use super::{super::backend::*, depth::*, kind::*, list::*, path::*, state::*, symbol::*};
2
3use {
4 cursive::{style::*, utils::span::*, *},
5 std::{borrow::*, marker::*},
6};
7
8pub struct Node<BackendT>
14where
15 BackendT: TreeBackend,
16{
17 pub depth: usize,
19
20 pub kind: NodeKind,
22
23 pub id: BackendT::ID,
25
26 pub label: SpannedString<Style>,
28
29 pub label_size: Vec2,
36
37 pub branch_state: BranchState,
39
40 pub children: Option<NodeList<BackendT>>,
42
43 pub data: Option<BackendT::Data>,
45
46 backend: PhantomData<BackendT>,
47}
48
49impl<BackendT> Node<BackendT>
50where
51 BackendT: TreeBackend,
52{
53 pub fn new<IdT, LabelT>(depth: usize, kind: NodeKind, id: IdT, label: LabelT) -> Self
55 where
56 IdT: Into<BackendT::ID>,
57 LabelT: Into<SpannedString<Style>>,
58 {
59 let id = id.into();
60 let label = label.into();
61 let label_size = (label.width(), 1).into();
62 Self {
63 depth,
64 kind,
65 id,
66 label,
67 label_size,
68 branch_state: Default::default(),
69 children: None,
70 data: None,
71 backend: Default::default(),
72 }
73 }
74
75 pub fn symbol(&self, context: BackendT::Context) -> Symbol<'_> {
79 BackendT::symbol(self, context)
80 }
81
82 pub fn at_path(&self, path: NodePath) -> Option<&Self> {
84 if path.is_empty() { Some(self) } else { self.children.as_ref().and_then(|children| children.at_path(path)) }
85 }
86
87 pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Self> {
89 if path.is_empty() {
90 Some(self)
91 } else {
92 self.children.as_mut().and_then(|children| children.at_path_mut(path))
93 }
94 }
95
96 pub fn fill_path(&self, path: &mut NodePath, node: &Self) -> bool {
100 self.children.as_ref().map(|children| children.fill_path(path, node)).unwrap_or_default()
101 }
102
103 pub fn populate(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
111 where
112 BackendT::Context: Clone,
113 {
114 if depth.is_zero() || !self.kind.is_branch() {
115 return Ok(());
116 }
117
118 if self.children.is_none() {
119 BackendT::populate(self, context.clone())?;
120 }
121
122 depth.decrease();
123 if !depth.is_zero()
124 && let Some(children) = &mut self.children
125 {
126 for node in children {
127 node.populate(depth, context.clone())?;
128 }
129 }
130
131 Ok(())
132 }
133
134 pub fn add_child<IdT, LabelT>(&mut self, kind: NodeKind, id: IdT, label: LabelT)
138 where
139 IdT: Into<BackendT::ID>,
140 LabelT: Into<SpannedString<Style>>,
141 {
142 if !self.kind.is_branch() {
143 return;
144 }
145
146 if self.children.is_none() {
147 self.children = Some(Default::default());
148 }
149
150 self.children.as_mut().expect("children").add(self.depth + 1, kind, id, label);
151 }
152
153 pub fn insert_child<IdT, LabelT>(&mut self, index: usize, kind: NodeKind, id: IdT, label: LabelT)
157 where
158 IdT: Into<BackendT::ID>,
159 LabelT: Into<SpannedString<Style>>,
160 {
161 if !self.kind.is_branch() {
162 return;
163 }
164
165 if self.children.is_none() {
166 self.children = Some(Default::default());
167 }
168
169 self.children.as_mut().expect("children").insert(index, self.depth + 1, kind, id, label);
170 }
171
172 pub fn expand(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
180 where
181 BackendT::Context: Clone,
182 {
183 if depth.is_zero() || !self.kind.is_branch() {
184 return Ok(());
185 }
186
187 if !self.branch_state.is_expanded() {
188 self.populate(Some(1), context.clone())?;
189 self.branch_state = BranchState::Expanded;
190 }
191
192 depth.decrease();
193 if !depth.is_zero()
194 && let Some(children) = &mut self.children
195 {
196 children.expand(depth, context.clone())?;
197 }
198
199 Ok(())
200 }
201
202 pub fn collapse(&mut self, mut depth: Option<usize>) {
208 if depth.is_zero() || !self.kind.is_branch() {
209 return;
210 }
211
212 if !self.branch_state.is_collapsed() {
213 self.branch_state = BranchState::Collapsed;
214 }
215
216 depth.decrease();
217 if !depth.is_zero()
218 && let Some(children) = &mut self.children
219 {
220 children.collapse(depth);
221 }
222 }
223
224 pub fn toggle_branch_state(&mut self, context: BackendT::Context) -> Result<(), BackendT::Error>
230 where
231 BackendT::Context: Clone,
232 {
233 if !self.kind.is_branch() {
234 return Ok(());
235 }
236
237 _ = match self.branch_state {
238 BranchState::Collapsed => self.expand(Some(1), context)?,
239 BranchState::Expanded => self.collapse(Some(1)),
240 };
241
242 Ok(())
243 }
244
245 pub fn data(&mut self, context: BackendT::Context) -> Result<Option<Cow<'_, BackendT::Data>>, BackendT::Error>
249 where
250 BackendT::Data: Clone,
251 {
252 if self.data.is_none() {
253 if let Some((data, cache)) = BackendT::data(self, context)? {
254 if cache {
255 self.data = Some(data);
256 } else {
257 return Ok(Some(Cow::Owned(data)));
258 }
259 }
260 }
261
262 Ok(self.data.as_ref().map(Cow::Borrowed))
263 }
264}