generic_tree/lib.rs
1//! This crate provides a very simple, intuitive API for storing data in a tree-like structure.
2//!
3//! # Example
4//!
5//! ```
6//! use generic_tree::{Tree, Node};
7//!
8//! struct Data;
9//!
10//! // Create a root Node
11//! let mut root = Node::new("root", Data);
12//!
13//! // Create a tree from it
14//! let mut tree = Tree::init(root);
15//!
16//! // Create a child
17//! let child = Node::new("child", Data);
18//!
19//! // And add it as a child of `root`
20//! tree.add_node(&["root"], child);
21//!
22//! // Get a reference to the child
23//! let child = tree.get_node(&["root", "child"]).unwrap();
24//! ```
25
26/// A Tree represents and owns a collection of Nodes. It should be the go-to point for interacting
27/// with elements wihtin the structure.
28pub struct Tree<K, V> {
29 root: Node<K, V>,
30}
31
32/// A single building block to represent an element within a Tree. Itself can contain a list of
33/// more Nodes.
34/// It should eventually be part of a Tree and it shouldn't be necessary to keep it around on its
35/// own.
36pub struct Node<K, V> {
37 key: K,
38 value: V,
39 children: Vec<Box<Node<K, V>>>,
40}
41
42#[derive(Debug)]
43pub enum Error {
44 InvalidPath,
45}
46
47impl<K, V> Tree<K, V>
48where
49 K: PartialEq,
50{
51 /// Create a new tree, given the root Node `root`.
52 pub fn init(root: Node<K, V>) -> Self {
53 Self { root }
54 }
55
56 /// Get a reference to a specific Node from the tree, resolved by the list provided by `path`.
57 ///
58 /// # Errors
59 /// Returns an `Err` if `path` doesn't resolve to a Node.
60 ///
61 /// # Examples
62 ///
63 /// ```
64 /// # use generic_tree::{Tree, Node};
65 /// let mut root = Node::new("root", 1);
66 /// let child = Node::new("child", 2);
67 /// root.add_child(child);
68 ///
69 /// let mut tree = Tree::init(root);
70 ///
71 /// assert!(tree.get_node(&["root"]).is_ok());
72 /// assert!(tree.get_node(&["root", "child"]).is_ok());
73 /// assert!(tree.get_node(&["boot"]).is_err());
74 /// assert!(tree.get_node(&["root", "child", "noop"]).is_err());
75 /// ```
76 pub fn get_node<Q>(&self, path: &[Q]) -> Result<&Node<K, V>, Error>
77 where
78 Q: PartialEq<K>,
79 {
80 if &path[0] == self.root.key() {
81 self.root.get_child(&path[1..])
82 } else {
83 Err(Error::InvalidPath)
84 }
85 }
86
87 /// Get a mutable reference to a specific Node from the tree, resolved by the list provided by `path`.
88 ///
89 /// # Errors
90 /// Returns an `Err` if `path` doesn't resolve to a Node.
91 ///
92 /// # Examples
93 ///
94 /// ```
95 /// use generic_tree::{Tree, Node};
96 ///
97 /// let mut root = Node::new("root", 1);
98 /// let child = Node::new("child", 2);
99 /// root.add_child(child);
100 ///
101 /// let mut tree = Tree::init(root);
102 ///
103 /// let mut node = tree.get_mut_node(&["root", "child"]).unwrap();
104 /// assert_eq!(node.value(), &2);
105 ///
106 /// *node.mut_value() = 42;
107 /// # assert_eq!(node.value(), &42);
108 /// ```
109 pub fn get_mut_node<Q>(&mut self, path: &[Q]) -> Result<&mut Node<K, V>, Error>
110 where
111 Q: PartialEq<K>,
112 {
113 if &path[0] == self.root.key() {
114 self.root.get_mut_child(&path[1..])
115 } else {
116 Err(Error::InvalidPath)
117 }
118 }
119
120 /// Add a Node as a child to the Node resolved by `path`. If there was already a Node with the
121 /// same key, that old Node is returned.
122 ///
123 /// # Errors
124 /// Returns an `Err` if `path` doesn't resolve to a Node.
125 ///
126 /// # Examples
127 ///
128 /// ```
129 /// # use generic_tree::{Tree, Node};
130 /// let mut root = Node::new("root", 1);
131 /// let mut tree = Tree::init(root);
132 /// # assert!(tree.get_node(&["root", "child"]).is_err());
133 ///
134 /// let child = Node::new("child", 2);
135 /// tree.add_node(&["root"], child);
136 /// # assert!(tree.get_node(&["root", "child"]).is_ok());
137 /// # // Add a second child and verify the first one is returned
138 /// # let child = Node::new("child", 3);
139 /// # let old_child = tree.add_node(&["root"], child).unwrap().unwrap();
140 /// # assert_eq!(old_child.value(), &2);
141 /// ```
142 pub fn add_node<Q>(
143 &mut self,
144 path: &[Q],
145 node: Node<K, V>,
146 ) -> Result<Option<Box<Node<K, V>>>, Error>
147 where
148 Q: PartialEq<K>,
149 {
150 if path.is_empty() {
151 return Err(Error::InvalidPath);
152 }
153
154 if &path[0] == self.root.key() {
155 self.root.add_child_at_path(&path[1..], node)
156 } else {
157 Err(Error::InvalidPath)
158 }
159 }
160
161 /// Remove a Node from the tree resolved by `path`.
162 ///
163 /// # Errors
164 /// Returns an `Err` if `path` doesn't resolve to a Node.
165 ///
166 /// # Examples
167 ///
168 /// ```
169 /// # use generic_tree::{Tree, Node};
170 /// let mut root = Node::new("root", 1);
171 /// let child = Node::new("child", 2);
172 /// root.add_child(child);
173 /// let mut tree = Tree::init(root);
174 /// # assert!(tree.get_node(&["root", "child"]).is_ok());
175 ///
176 /// assert!(tree.remove_node(&["root", "child"]).is_ok());
177 /// ```
178 pub fn remove_node<Q>(&mut self, path: &[Q]) -> Result<Box<Node<K, V>>, Error>
179 where
180 Q: PartialEq<K>,
181 {
182 // An empty path is not allowed. Furthermore, a path containing a single element could only
183 // match the root itself, and can't be removed. For this, use `remove_root`.
184 if path.len() < 2 {
185 return Err(Error::InvalidPath);
186 }
187
188 if &path[0] == self.root.key() {
189 self.root.remove_child(&path[1..])
190 } else {
191 Err(Error::InvalidPath)
192 }
193 }
194}
195
196impl<K, V> Node<K, V>
197where
198 K: PartialEq,
199{
200 /// Creates a new Node.
201 ///
202 /// # Examples
203 ///
204 /// ```
205 /// use generic_tree::Node;
206 ///
207 /// let node = Node::new("some_key".to_owned(), 42);
208 /// assert_eq!(node.key(), "some_key");
209 /// assert_eq!(node.value(), &42);
210 /// ```
211 pub fn new(key: K, value: V) -> Self {
212 Self {
213 key,
214 value,
215 children: Vec::new(),
216 }
217 }
218
219 /// Add a child Node to the current Node. If there already is a child with the same `key`, that
220 /// child will be returned.
221 ///
222 /// # Examples
223 ///
224 /// ```
225 /// use generic_tree::Node;
226 ///
227 /// let mut parent = Node::new("parent".to_owned(), 2);
228 /// let child = Node::new("child".to_owned(), 3);
229 ///
230 /// assert!(parent.add_child(child).is_none());
231 ///
232 /// let child = Node::new("child".to_owned(), 4);
233 /// let prev_child = parent.add_child(child).unwrap();
234 /// assert_eq!(prev_child.value(), &3);
235 /// ```
236 pub fn add_child(&mut self, child: Node<K, V>) -> Option<Box<Node<K, V>>> {
237 let child = Box::new(child);
238
239 let mut old_value = None;
240 for i in 0..self.children.len() {
241 if self.children[i] == child {
242 old_value = Some(self.children.remove(i));
243 break;
244 }
245 }
246
247 self.children.push(child);
248
249 old_value
250 }
251
252 /// Add a child Node at a specific descendent path. If there was already such a child, it will
253 /// be returned.
254 ///
255 /// # Errors
256 ///
257 /// Will return `Err` if `path` can't be resolved.
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// use generic_tree::Node;
263 ///
264 /// let mut grandparent = Node::new("grandparent".to_owned(), 1);
265 /// let mut parent = Node::new("parent".to_owned(), 2);
266 /// grandparent.add_child(parent);
267 ///
268 /// // Tree structure:
269 /// // grandparent -> parent
270 /// assert!(grandparent.get_child(&["parent", "child"]).is_err());
271 ///
272 /// let child = Node::new("child".to_owned(), 3);
273 /// assert!(grandparent.add_child_at_path(&["parent"], child).is_ok());
274 /// assert!(grandparent.get_child(&["parent", "child"]).is_ok());
275 /// ```
276 pub fn add_child_at_path<Q>(
277 &mut self,
278 path: &[Q],
279 child: Node<K, V>,
280 ) -> Result<Option<Box<Node<K, V>>>, Error>
281 where
282 Q: PartialEq<K>,
283 {
284 let parent = self.get_mut_child(path)?;
285
286 Ok(parent.add_child(child))
287 }
288
289 /// Get a child node based on a list of keys.
290 ///
291 /// # Errors
292 ///
293 /// Will return `Err` if `path` can't be resolved.
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use generic_tree::Node;
299 ///
300 /// let mut grandparent = Node::new("grandparent".to_owned(), 1);
301 /// let mut parent = Node::new("parent".to_owned(), 2);
302 /// let child = Node::new("child".to_owned(), 3);
303 ///
304 /// assert!(parent.add_child(child).is_none());
305 /// assert!(grandparent.add_child(parent).is_none());
306 ///
307 /// // Tree structure:
308 /// // grandparent -> parent -> child
309 /// assert!(grandparent.get_child(&["parent", "child"]).is_ok());
310 /// ```
311 pub fn get_child<Q>(&self, path: &[Q]) -> Result<&Node<K, V>, Error>
312 where
313 Q: PartialEq<K>,
314 {
315 if path.is_empty() {
316 return Ok(self);
317 }
318
319 let child = &path[0];
320 let path = &path[1..];
321
322 for entry in &self.children {
323 if child == entry.key() {
324 return entry.get_child(path);
325 }
326 }
327
328 Err(Error::InvalidPath)
329 }
330
331 /// Get mutable a child node based on a list of keys.
332 ///
333 /// # Errors
334 ///
335 /// Will return `Err` if `path` can't be resolved.
336 ///
337 /// # Examples
338 ///
339 /// ```
340 /// use generic_tree::Node;
341 ///
342 /// # let mut grandparent = Node::new("grandparent".to_owned(), 1);
343 /// # let mut parent = Node::new("parent".to_owned(), 2);
344 /// # let child = Node::new("child".to_owned(), 3);
345 ///
346 /// # assert!(parent.add_child(child).is_none());
347 /// # assert!(grandparent.add_child(parent).is_none());
348 ///
349 /// // Tree structure:
350 /// // grandparent -> parent -> child
351 /// assert!(grandparent.get_mut_child(&["parent", "child"]).is_ok());
352 /// ```
353 pub fn get_mut_child<Q>(&mut self, path: &[Q]) -> Result<&mut Node<K, V>, Error>
354 where
355 Q: PartialEq<K>,
356 {
357 if path.is_empty() {
358 return Ok(self);
359 }
360
361 let child = &path[0];
362 let path = &path[1..];
363
364 for entry in &mut self.children {
365 if child == entry.key() {
366 return entry.get_mut_child(path);
367 }
368 }
369
370 Err(Error::InvalidPath)
371 }
372
373 /// Remove a child node based on a list of keys. A `boxed` Node is returned if found, None
374 /// otherwise.
375 ///
376 /// # Errors
377 ///
378 /// Will return `Err` if `path` can't be resolved.
379 ///
380 /// # Examples
381 ///
382 /// ```
383 /// use generic_tree::Node;
384 ///
385 /// let mut grandparent = Node::new("grandparent".to_owned(), 1);
386 /// let mut parent = Node::new("parent".to_owned(), 2);
387 /// let child = Node::new("child".to_owned(), 3);
388 ///
389 /// parent.add_child(child);
390 /// grandparent.add_child(parent);
391 ///
392 /// // Tree structure:
393 /// // grandparent -> parent -> child
394 ///
395 /// assert!(grandparent.remove_child(&["parent", "child"]).is_ok());
396 /// assert!(grandparent.remove_child(&["parent", "child"]).is_err());
397 /// ```
398 pub fn remove_child<Q>(&mut self, path: &[Q]) -> Result<Box<Node<K, V>>, Error>
399 where
400 Q: PartialEq<K>,
401 {
402 if path.is_empty() {
403 return Err(Error::InvalidPath);
404 }
405
406 let child = &path[0];
407 let path = &path[1..];
408
409 for i in 0..self.children.len() {
410 if child == self.children[i].key() {
411 if path.is_empty() {
412 return Ok(self.children.remove(i));
413 } else {
414 return self.children[i].remove_child(path);
415 }
416 }
417 }
418
419 Err(Error::InvalidPath)
420 }
421
422 /// Get a reference the value contained within the node.
423 ///
424 /// # Examples
425 ///
426 /// ```
427 /// use generic_tree::Node;
428 ///
429 /// let node = Node::new("some_key".to_owned(), 42);
430 ///
431 /// assert_eq!(node.value(), &42);
432 /// ```
433 pub fn value(&self) -> &V {
434 &self.value
435 }
436
437 /// Get a muteable reference to the value contained within the node.
438 ///
439 /// # Examples
440 ///
441 /// ```
442 /// use generic_tree::Node;
443 ///
444 /// let mut node = Node::new("some_key".to_owned(), 42);
445 ///
446 /// let mut value = node.mut_value();
447 /// assert_eq!(value, &42);
448 ///
449 /// *value = 43;
450 /// assert_eq!(node.value(), &43);
451 /// ```
452 pub fn mut_value(&mut self) -> &mut V {
453 &mut self.value
454 }
455
456 /// Get a reference to the key of the node.
457 ///
458 /// # Examples
459 ///
460 /// ```
461 /// use generic_tree::Node;
462 ///
463 /// let mut node = Node::new("some_key".to_owned(), 42);
464 ///
465 /// assert_eq!(node.key(), "some_key");
466 /// ```
467 pub fn key(&self) -> &K {
468 &self.key
469 }
470}
471
472impl<K, V> PartialEq for Node<K, V>
473where
474 K: PartialEq,
475{
476 fn eq(&self, other: &Self) -> bool {
477 self.key == other.key
478 }
479}
480
481impl<K, V> PartialEq<K> for Node<K, V>
482where
483 K: PartialEq,
484{
485 fn eq(&self, other: &K) -> bool {
486 &self.key == other
487 }
488}
489
490impl std::fmt::Display for Error {
491 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
492 match self {
493 Error::InvalidPath => write!(f, "InvalidPath"),
494 }
495 }
496}