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,
33
34 pub branch_state: BranchState,
36
37 pub children: Option<NodeList<BackendT>>,
39
40 pub data: Option<BackendT::Data>,
42
43 backend: PhantomData<BackendT>,
44}
45
46impl<BackendT> Node<BackendT>
47where
48 BackendT: TreeBackend,
49{
50 pub fn new(depth: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) -> Self {
52 let representation_size = (representation.width(), 1).into();
53 Self {
54 depth,
55 kind,
56 id,
57 representation,
58 representation_size,
59 branch_state: Default::default(),
60 children: None,
61 data: None,
62 backend: Default::default(),
63 }
64 }
65
66 pub fn symbol(&self, context: BackendT::Context) -> Symbol<'_> {
70 BackendT::symbol(self, context)
71 }
72
73 pub fn at_path(&self, path: NodePath) -> Option<&Self> {
75 if path.is_empty() { Some(self) } else { self.children.as_ref().and_then(|children| children.at_path(path)) }
76 }
77
78 pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Self> {
80 if path.is_empty() {
81 Some(self)
82 } else {
83 self.children.as_mut().and_then(|children| children.at_path_mut(path))
84 }
85 }
86
87 pub fn fill_path(&self, path: &mut NodePath, node: &Self) -> bool {
91 self.children.as_ref().map(|children| children.fill_path(path, node)).unwrap_or_default()
92 }
93
94 pub fn populate(&mut self, mut depth: Option<usize>, context: BackendT::Context) -> Result<(), BackendT::Error>
100 where
101 BackendT::Context: Clone,
102 {
103 if depth.is_zero() || !self.kind.is_branch() {
104 return Ok(());
105 }
106
107 if self.children.is_none() {
108 BackendT::populate(self, context.clone())?;
109 }
110
111 depth.decrease();
112 if !depth.is_zero()
113 && let Some(children) = &mut self.children
114 {
115 for node in children {
116 node.populate(depth, context.clone())?;
117 }
118 }
119
120 Ok(())
121 }
122
123 pub fn add_child(&mut self, kind: NodeKind, id: BackendT::ID, representation: Representation) {
125 if !self.kind.is_branch() {
126 return;
127 }
128
129 if self.children.is_none() {
130 self.children = Some(Default::default());
131 }
132
133 self.children.as_mut().expect("children").add(self.depth + 1, kind, id, representation);
134 }
135
136 pub fn insert_child(&mut self, index: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) {
138 if !self.kind.is_branch() {
139 return;
140 }
141
142 if self.children.is_none() {
143 self.children = Some(Default::default());
144 }
145
146 self.children.as_mut().expect("children").insert(index, self.depth + 1, kind, id, representation);
147 }
148
149 pub fn expand_branch(&mut self, context: BackendT::Context) -> Result<bool, BackendT::Error>
153 where
154 BackendT::Context: Clone,
155 {
156 if !self.kind.is_branch() || self.branch_state.is_expanded() {
157 return Ok(false);
158 }
159
160 self.populate(Some(1), context)?;
161 self.branch_state = BranchState::Expanded;
162 Ok(true)
163 }
164
165 pub fn collapse_branch(&mut self) -> bool {
169 if !self.kind.is_branch() || self.branch_state.is_collapsed() {
170 return false;
171 }
172
173 self.branch_state = BranchState::Collapsed;
174 true
175 }
176
177 pub fn toggle_branch_state(&mut self, context: BackendT::Context) -> Result<(), BackendT::Error>
183 where
184 BackendT::Context: Clone,
185 {
186 if !self.kind.is_branch() {
187 return Ok(());
188 }
189
190 match self.branch_state {
191 BranchState::Collapsed => {
192 self.expand_branch(context)?;
193 }
194 BranchState::Expanded => {
195 self.collapse_branch();
196 }
197 }
198
199 Ok(())
200 }
201
202 pub fn data(&mut self, context: BackendT::Context) -> Result<Option<Cow<'_, BackendT::Data>>, BackendT::Error>
206 where
207 BackendT::Data: Clone,
208 {
209 if self.data.is_none() {
210 if let Some((data, cache)) = BackendT::data(self, context)? {
211 if cache {
212 self.data = Some(data);
213 } else {
214 return Ok(Some(Cow::Owned(data)));
215 }
216 }
217 }
218
219 Ok(self.data.as_ref().map(Cow::Borrowed))
220 }
221}