socarel/node.rs
1use std::collections::HashMap as Map;
2
3//---- Structs ----//
4
5/// Trait to define structs that model a node content.
6pub trait NodeContent {
7 /// Constructor.
8 ///
9 /// # Arguments
10 ///
11 /// * `content` - Node content.
12 ///
13 /// # Return
14 ///
15 /// * An [`Option`] with the node content.
16 ///
17 fn new(content: &str) -> Option<Self> where Self: Sized;
18
19 /// Get node value.
20 ///
21 /// # Return
22 ///
23 /// * Node value.
24 ///
25 fn get_val(&self) -> &str;
26
27 /// Generate node content.
28 ///
29 /// Use by serializers to create back the string of a node that is parsed by a NodeContent implementer.
30 ///
31 /// # Return
32 ///
33 /// * Node content.
34 ///
35 fn gen_content(&self) -> String;
36}
37
38/// Default [`NodeContent`] struct.
39///
40/// It simply holds the content as is, without parsing or modifying it.
41#[derive(Debug)]
42pub struct RawNode {
43 /// Node content.
44 content: String
45}
46
47impl NodeContent for RawNode {
48 fn new(content: &str) -> Option<Self> {
49 Some(
50 Self {
51 content: String::from(content)
52 }
53 )
54 }
55
56 fn get_val(&self) -> &str {
57 &self.content
58 }
59
60 fn gen_content(&self) -> String {
61 String::from(self.get_val())
62 }
63}
64
65/// Struct that contains a tree node.
66#[derive(Debug)]
67pub struct Node<T: NodeContent = RawNode> {
68 /// Node content.
69 content: T,
70 /// Nodel level.
71 level: usize,
72 /// Parent node index in the tree array.
73 parent_position: Option<usize>,
74 // Map of content/node index, to find a child by name.
75 child_map: Map<String, usize>,
76 /// Index of current node in the parent [`children`][`Node::children`] array.
77 parents_children_pos: Option<usize>,
78 /// Array that contains indexes of of children nodes.
79 children: Vec<usize>
80}
81
82//---- Implementations ----//
83
84impl<T: NodeContent> Node<T> {
85 /// Create new root node.
86 ///
87 /// # Arguments
88 ///
89 /// * `content` - Node content.
90 ///
91 /// # Return
92 ///
93 /// * Node struct or None if content parsing fails.
94 ///
95 pub fn new_root(content: &str) -> Option<Self> {
96 Self::new_node(content, 1)
97 }
98
99 /// Create new node.
100 ///
101 /// # Arguments
102 ///
103 /// * `content` - Node content.
104 /// * `level` - Node level.
105 ///
106 /// # Return
107 ///
108 /// * Node struct or None if content parsing fails.
109 ///
110 pub fn new_node(content: &str, level: usize) -> Option<Self> {
111 if let Some(content_node) = NodeContent::new(content) {
112 Some(
113 Node {
114 content: content_node,
115 level,
116 parent_position: None,
117 child_map: Map::new(),
118 parents_children_pos: None,
119 children: vec!()
120 }
121 )
122 }
123 else {
124 None
125 }
126 }
127
128 /// Set content.
129 ///
130 /// # Arguments
131 ///
132 /// * `content` - Node content.
133 ///
134 /// # Return
135 ///
136 /// * Nothing.
137 ///
138 pub fn set_content(&mut self, content: T) {
139 self.content = content;
140 }
141
142 /// Get content. Move self.
143 ///
144 /// # Return
145 ///
146 /// * Node content.
147 ///
148 pub fn get_content(self) -> T {
149 self.content
150 }
151
152 /// Get content reference.
153 ///
154 /// # Return
155 ///
156 /// * Node content reference.
157 ///
158 pub fn get_content_ref(&self) -> &T {
159 &self.content
160 }
161
162 /// Set level.
163 ///
164 /// # Arguments
165 ///
166 /// * `level` - Node level.
167 ///
168 /// # Return
169 ///
170 /// * Nothing.
171 ///
172 pub fn set_level(&mut self, level: usize) {
173 self.level = level;
174 }
175
176 /// Get level.
177 ///
178 /// # Return
179 ///
180 /// * Node level.
181 ///
182 pub fn get_level(&self) -> usize {
183 self.level
184 }
185
186 /// Get number of children.
187 ///
188 /// # Return
189 ///
190 /// * Number of children.
191 ///
192 pub fn get_num_chuildren(&self) -> usize {
193 self.children.len()
194 }
195
196 /// Set parent node position.
197 ///
198 /// # Arguments
199 ///
200 /// * `parent_position` - Parent node position.
201 ///
202 /// # Return
203 ///
204 /// * Nothing.
205 ///
206 pub fn set_parent_position(&mut self, parent_position: usize) {
207 self.parent_position = Some(parent_position);
208 }
209
210 /// Get parent node position.
211 ///
212 /// # Return
213 ///
214 /// * Parent node position..
215 ///
216 pub fn get_parent_position(&self) -> Option<usize> {
217 self.parent_position
218 }
219
220 /// Set parent's children array position.
221 ///
222 /// # Arguments
223 ///
224 /// * `parents_children_pos` - Position of current node in parent's children array.
225 ///
226 /// # Return
227 ///
228 /// * Nothing.
229 ///
230 pub fn set_parents_children_pos(&mut self, parents_children_pos: usize) {
231 self.parents_children_pos = Some(parents_children_pos);
232 }
233
234 /// Get parent's children array position.
235 ///
236 /// * Position of current node in parent's children array.
237 ///
238 pub fn get_parents_children_pos(&self) -> Option<usize> {
239 self.parents_children_pos
240 }
241
242 /// Add new child.
243 ///
244 /// # Arguments
245 ///
246 /// * `node_content` - Node content.
247 /// * `node_index` - Node index.
248 ///
249 /// # Return
250 ///
251 /// * Nothing.
252 ///
253 pub fn add_child(&mut self, node_content: String, node_index: usize) {
254 self.children.push(node_index);
255 self.child_map.insert(node_content, node_index);
256 }
257
258 /// Remove child.
259 ///
260 /// # Arguments
261 ///
262 /// * `node_index` - Node index.
263 ///
264 /// # Return
265 ///
266 /// * Nothing.
267 ///
268 pub fn remove_child(&mut self, node_content: &str, node_index: usize) {
269 self.child_map.remove(node_content);
270 self.children[node_index] = usize::MAX;
271 }
272
273 /// Update child map.
274 ///
275 /// # Arguments
276 ///
277 /// * `node_content` - Current node content.
278 /// * `new_node_content` - New node content.
279 ///
280 /// # Return
281 ///
282 /// * An [`Option`] with the node index.
283 ///
284 pub fn update_child(&mut self, node_content: &str, new_node_content: &str) -> Option<usize> {
285 if let Some(node_index) = self.child_map.remove(node_content) {
286 self.child_map.insert(String::from(new_node_content), node_index);
287 return Some(node_index);
288 }
289 None
290 }
291
292 /// Get child index using node content.
293 ///
294 /// # Arguments
295 ///
296 /// * `node_content` - Current node content.
297 ///
298 /// # Return
299 ///
300 /// * An [`Option`] with the node index.
301 ///
302 pub fn get_child(&self, node_content: &str) -> Option<usize> {
303 if let Some(node_index) = self.child_map.get(node_content) {
304 Some(*node_index)
305 }
306 else {
307 None
308 }
309 }
310
311 /// Get children array reference.
312 ///
313 /// # Return
314 ///
315 /// * Array ref.
316 ///
317 pub fn get_children_ref(&self) -> &[usize] {
318 &self.children
319 }
320}