1use super::{super::backend::*, depth::*, kind::*, list::*, path::*, representation::*, state::*, symbol::*};
2
3use {
4 cursive::*,
5 std::{borrow::*, marker::*},
6};
7
8pub struct Node<BackendT, ContextT, ErrorT, IdT, DataT> {
14 pub depth: usize,
16
17 pub kind: NodeKind,
19
20 pub id: IdT,
22
23 pub representation: Representation,
25
26 pub representation_size: XY<usize>,
30
31 pub branch_state: BranchState,
33
34 pub children: Option<NodeList<BackendT, ContextT, ErrorT, IdT, DataT>>,
36
37 pub data: Option<DataT>,
39
40 backend: PhantomData<BackendT>,
41 context: PhantomData<ContextT>,
42 error: PhantomData<ErrorT>,
43}
44
45impl<BackendT, ContextT, ErrorT, IdT, DataT> Node<BackendT, ContextT, ErrorT, IdT, DataT>
46where
47 BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
48{
49 pub fn new(depth: usize, kind: NodeKind, id: IdT, representation: Representation) -> Self {
51 let representation_size = (representation.width(), 1).into();
52 Self {
53 depth,
54 kind,
55 id,
56 representation,
57 representation_size,
58 branch_state: Default::default(),
59 children: None,
60 data: None,
61 backend: Default::default(),
62 context: Default::default(),
63 error: Default::default(),
64 }
65 }
66
67 pub fn symbol(&self, context: ContextT) -> Symbol<'_> {
71 BackendT::symbol(self, context)
72 }
73
74 pub fn at_path(&self, path: NodePath) -> Option<&Self> {
76 if path.is_empty() { Some(self) } else { self.children.as_ref().and_then(|children| children.at_path(path)) }
77 }
78
79 pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Self> {
81 if path.is_empty() {
82 Some(self)
83 } else {
84 self.children.as_mut().and_then(|children| children.at_path_mut(path))
85 }
86 }
87
88 pub fn fill_path(&self, path: &mut NodePath, node: &Self) -> bool {
92 self.children.as_ref().map(|children| children.fill_path(path, node)).unwrap_or_default()
93 }
94
95 pub fn populate(&mut self, mut depth: Option<usize>, context: ContextT) -> Result<(), ErrorT>
101 where
102 ContextT: Clone,
103 {
104 if depth.is_zero() || !self.kind.is_branch() {
105 return Ok(());
106 }
107
108 if self.children.is_none() {
109 BackendT::populate(self, context.clone())?;
110 }
111
112 depth.decrease();
113 if !depth.is_zero()
114 && let Some(children) = &mut self.children
115 {
116 for node in children {
117 node.populate(depth, context.clone())?;
118 }
119 }
120
121 Ok(())
122 }
123
124 pub fn add_child(&mut self, kind: NodeKind, id: IdT, representation: Representation) {
126 if !self.kind.is_branch() {
127 return;
128 }
129
130 if self.children.is_none() {
131 self.children = Some(Default::default());
132 }
133
134 self.children.as_mut().expect("children").add(self.depth + 1, kind, id, representation);
135 }
136
137 pub fn insert_child(&mut self, index: usize, kind: NodeKind, id: IdT, representation: Representation) {
139 if !self.kind.is_branch() {
140 return;
141 }
142
143 if self.children.is_none() {
144 self.children = Some(Default::default());
145 }
146
147 self.children.as_mut().expect("children").insert(index, self.depth + 1, kind, id, representation);
148 }
149
150 pub fn expand_branch(&mut self, context: ContextT) -> Result<bool, ErrorT>
154 where
155 ContextT: Clone,
156 {
157 if !self.kind.is_branch() || self.branch_state.is_expanded() {
158 return Ok(false);
159 }
160
161 self.populate(Some(1), context)?;
162 self.branch_state = BranchState::Expanded;
163 Ok(true)
164 }
165
166 pub fn collapse_branch(&mut self) -> bool {
170 if !self.kind.is_branch() || self.branch_state.is_collapsed() {
171 return false;
172 }
173
174 self.branch_state = BranchState::Collapsed;
175 true
176 }
177
178 pub fn toggle_branch_state(&mut self, context: ContextT) -> Result<(), ErrorT>
184 where
185 ContextT: Clone,
186 {
187 if !self.kind.is_branch() {
188 return Ok(());
189 }
190
191 match self.branch_state {
192 BranchState::Collapsed => {
193 self.expand_branch(context)?;
194 }
195 BranchState::Expanded => {
196 self.collapse_branch();
197 }
198 }
199
200 Ok(())
201 }
202
203 pub fn data(&mut self, context: ContextT) -> Result<Option<Cow<'_, DataT>>, ErrorT>
207 where
208 DataT: Clone,
209 {
210 if self.data.is_none() {
211 if let Some((data, cache)) = BackendT::data(self, context)? {
212 if cache {
213 self.data = Some(data);
214 } else {
215 return Ok(Some(Cow::Owned(data)));
216 }
217 }
218 }
219
220 Ok(self.data.as_ref().map(Cow::Borrowed))
221 }
222}