cursive_tree/model/
node.rs1use super::{super::backend::*, depth::*, kind::*, list::*, path::*, representation::*, state::*, symbol::*};
2
3use {
4 cursive::*,
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 representation: Representation,
28
29 pub representation_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(depth: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) -> Self {
55 let representation_size = (representation.width(), 1).into();
56 Self {
57 depth,
58 kind,
59 id,
60 representation,
61 representation_size,
62 branch_state: Default::default(),
63 children: None,
64 data: None,
65 backend: Default::default(),
66 }
67 }
68
69 pub fn symbol(&self, context: BackendT::Context) -> Symbol<'_> {
73 BackendT::symbol(self, context)
74 }
75
76 pub fn at_path(&self, path: NodePath) -> Option<&Self> {
78 if path.is_empty() { Some(self) } else { self.children.as_ref().and_then(|children| children.at_path(path)) }
79 }
80
81 pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Self> {
83 if path.is_empty() {
84 Some(self)
85 } else {
86 self.children.as_mut().and_then(|children| children.at_path_mut(path))
87 }
88 }
89
90 pub fn fill_path(&self, path: &mut NodePath, node: &Self) -> bool {
94 self.children.as_ref().map(|children| children.fill_path(path, node)).unwrap_or_default()
95 }
96
97 pub fn populate(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
105 where
106 BackendT::Context: Clone,
107 {
108 if depth.is_zero() || !self.kind.is_branch() {
109 return Ok(());
110 }
111
112 if self.children.is_none() {
113 BackendT::populate(self, context.clone())?;
114 }
115
116 depth.decrease();
117 if !depth.is_zero()
118 && let Some(children) = &mut self.children
119 {
120 for node in children {
121 node.populate(depth, context.clone())?;
122 }
123 }
124
125 Ok(())
126 }
127
128 pub fn add_child(&mut self, kind: NodeKind, id: BackendT::ID, representation: Representation) {
132 if !self.kind.is_branch() {
133 return;
134 }
135
136 if self.children.is_none() {
137 self.children = Some(Default::default());
138 }
139
140 self.children.as_mut().expect("children").add(self.depth + 1, kind, id, representation);
141 }
142
143 pub fn insert_child(&mut self, index: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) {
147 if !self.kind.is_branch() {
148 return;
149 }
150
151 if self.children.is_none() {
152 self.children = Some(Default::default());
153 }
154
155 self.children.as_mut().expect("children").insert(index, self.depth + 1, kind, id, representation);
156 }
157
158 pub fn expand(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
166 where
167 BackendT::Context: Clone,
168 {
169 if depth.is_zero() || !self.kind.is_branch() {
170 return Ok(());
171 }
172
173 if !self.branch_state.is_expanded() {
174 self.populate(Some(1), context.clone())?;
175 self.branch_state = BranchState::Expanded;
176 }
177
178 depth.decrease();
179 if !depth.is_zero()
180 && let Some(children) = &mut self.children
181 {
182 children.expand(depth, context.clone())?;
183 }
184
185 Ok(())
186 }
187
188 pub fn collapse(&mut self, mut depth: Option<usize>) {
194 if depth.is_zero() || !self.kind.is_branch() {
195 return;
196 }
197
198 if !self.branch_state.is_collapsed() {
199 self.branch_state = BranchState::Collapsed;
200 }
201
202 depth.decrease();
203 if !depth.is_zero()
204 && let Some(children) = &mut self.children
205 {
206 children.collapse(depth);
207 }
208 }
209
210 pub fn toggle_branch_state(&mut self, context: BackendT::Context) -> Result<(), BackendT::Error>
216 where
217 BackendT::Context: Clone,
218 {
219 if !self.kind.is_branch() {
220 return Ok(());
221 }
222
223 _ = match self.branch_state {
224 BranchState::Collapsed => self.expand(Some(1), context)?,
225 BranchState::Expanded => self.collapse(Some(1)),
226 };
227
228 Ok(())
229 }
230
231 pub fn data(&mut self, context: BackendT::Context) -> Result<Option<Cow<'_, BackendT::Data>>, BackendT::Error>
235 where
236 BackendT::Data: Clone,
237 {
238 if self.data.is_none() {
239 if let Some((data, cache)) = BackendT::data(self, context)? {
240 if cache {
241 self.data = Some(data);
242 } else {
243 return Ok(Some(Cow::Owned(data)));
244 }
245 }
246 }
247
248 Ok(self.data.as_ref().map(Cow::Borrowed))
249 }
250}