Skip to main content

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}