id_tree/
behaviors.rs

1use NodeId;
2
3///
4/// Describes the possible behaviors of the `Tree::remove_node` method.
5///
6pub enum RemoveBehavior {
7    ///
8    /// All children will be dropped recursively.  In other words, the entire sub-tree of the `Node`
9    /// being removed will be dropped from the tree.  Those `Node`s will no longer exist and
10    /// cannot be accessed even if you have the `NodeId` the previously pointed to them.
11    ///
12    /// This means even without using `Clone` you might end up with copies of invalid `NodeId`s.
13    /// Use this behavior with caution.
14    ///
15    /// ```
16    /// use id_tree::*;
17    /// use id_tree::InsertBehavior::*;
18    /// use id_tree::RemoveBehavior::*;
19    ///
20    /// let mut tree: Tree<i32> = Tree::new();
21    ///
22    /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
23    /// let child_id = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
24    /// let grandchild_id = tree.insert(Node::new(2), UnderNode(&child_id)).unwrap();
25    ///
26    /// let child = tree.remove_node(child_id, DropChildren).ok().unwrap();
27    ///
28    /// assert!(tree.get(&grandchild_id).is_err());
29    /// assert_eq!(tree.get(&root_id).unwrap().children().len(), 0);
30    /// assert_eq!(child.children().len(), 0);
31    /// assert_eq!(child.parent(), None);
32    /// ```
33    ///
34    DropChildren,
35
36    ///
37    /// If the removed `Node` (let's call it `A`) has a parent, `A`'s parent will become the
38    /// parent of `A`'s children.  This effectively just shifts them up one level in the `Tree`.
39    ///
40    /// If `A` doesn't have a parent, then this behaves exactly like
41    /// `RemoveBehavior::OrphanChildren`.
42    ///
43    /// ```
44    /// use id_tree::*;
45    /// use id_tree::InsertBehavior::*;
46    /// use id_tree::RemoveBehavior::*;
47    ///
48    /// let mut tree: Tree<i32> = Tree::new();
49    ///
50    /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
51    /// let child_id = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
52    /// let grandchild_id = tree.insert(Node::new(2), UnderNode(&child_id)).unwrap();
53    ///
54    /// let child = tree.remove_node(child_id, LiftChildren).ok().unwrap();
55    ///
56    /// assert!(tree.get(&grandchild_id).is_ok());
57    /// assert!(tree.get(&root_id).unwrap().children().contains(&grandchild_id));
58    /// assert_eq!(child.children().len(), 0);
59    /// assert_eq!(child.parent(), None);
60    /// ```
61    ///
62    LiftChildren,
63
64    ///
65    /// All children will have their parent references cleared.  This means nothing will point to
66    /// them, but they will still exist in the tree.  Those `Node`s can still be accessed provided
67    /// that you have the `NodeId` that points to them.
68    ///
69    /// ```
70    /// use id_tree::*;
71    /// use id_tree::InsertBehavior::*;
72    /// use id_tree::RemoveBehavior::*;
73    ///
74    /// let mut tree: Tree<i32> = Tree::new();
75    ///
76    /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
77    /// let child_id = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
78    /// let grandchild_id = tree.insert(Node::new(2), UnderNode(&child_id)).unwrap();
79    ///
80    /// let child = tree.remove_node(child_id, OrphanChildren).ok().unwrap();
81    ///
82    /// assert!(tree.get(&grandchild_id).is_ok());
83    /// assert_eq!(tree.get(&root_id).unwrap().children().len(), 0);
84    /// assert_eq!(child.children().len(), 0);
85    /// assert_eq!(child.parent(), None);
86    /// ```
87    ///
88    OrphanChildren,
89}
90
91///
92/// Describes the possible behaviors of the `Tree::move_node` method.
93///
94pub enum MoveBehavior<'a> {
95    ///
96    /// Sets the `Node` in question as the new root `Node`, leaving all children in their place (in
97    /// other words, they will travel with the `Node` being moved).
98    ///
99    /// If there is already a root `Node` in place, it will be attached as the last child of the new
100    /// root.
101    ///
102    /// ```
103    /// use id_tree::*;
104    /// use id_tree::InsertBehavior::*;
105    /// use id_tree::MoveBehavior::*;
106    ///
107    /// let mut tree: Tree<i32> = Tree::new();
108    ///
109    /// let root_id = tree.insert(Node::new(1), AsRoot).unwrap();
110    /// let child_id = tree.insert(Node::new(2),  UnderNode(&root_id)).unwrap();
111    /// let grandchild_id = tree.insert(Node::new(3), UnderNode(&child_id)).unwrap();
112    ///
113    /// tree.move_node(&grandchild_id, ToRoot).unwrap();
114    ///
115    /// assert_eq!(tree.root_node_id(), Some(&grandchild_id));
116    /// assert!(tree.get(&grandchild_id).unwrap().children().contains(&root_id));
117    /// assert!(!tree.get(&child_id).unwrap().children().contains(&grandchild_id));
118    /// ```
119    ///
120    ToRoot,
121
122    ///
123    /// Moves a `Node` inside the `Tree` to a new parent leaving all children in their place.
124    ///
125    /// If the new parent (let's call it `B`) is a descendant of the `Node` being moved (`A`), then
126    /// the direct child of `A` on the path from `A` to `B` will be shifted upwards to take the
127    /// place of its parent (`A`).  All other children of `A` will be left alone, meaning they will
128    /// travel with it down the `Tree`.
129    ///
130    /// Please note that during the "shift-up" part of the above scenario, the `Node` being shifted
131    /// up will always be added as the last child of its new parent.
132    ///
133    /// ```
134    /// use id_tree::*;
135    /// use id_tree::InsertBehavior::*;
136    /// use id_tree::MoveBehavior::*;
137    ///
138    /// let mut tree: Tree<i32> = Tree::new();
139    ///
140    /// let root_id = tree.insert(Node::new(1), AsRoot).ok().unwrap();
141    /// let first_child_id = tree.insert(Node::new(2),  UnderNode(&root_id)).unwrap();
142    /// let second_child_id = tree.insert(Node::new(3), UnderNode(&root_id)).unwrap();
143    /// let grandchild_id = tree.insert(Node::new(4), UnderNode(&first_child_id)).unwrap();
144    ///
145    /// tree.move_node(&grandchild_id, ToParent(&second_child_id)).unwrap();
146    ///
147    /// assert!(!tree.get(&first_child_id).unwrap().children().contains(&grandchild_id));
148    /// assert!(tree.get(&second_child_id).unwrap().children().contains(&grandchild_id));
149    /// ```
150    ///
151    ToParent(&'a NodeId),
152}
153
154///
155/// Describes the possible behaviors of the `Tree::insert` method.
156///
157pub enum InsertBehavior<'a> {
158    ///
159    /// Sets the root of the `Tree`.
160    ///
161    /// If there is already a root `Node` present in the tree, that `Node` is set as the first child
162    /// of the new root.
163    ///
164    /// ```
165    /// use id_tree::*;
166    /// use id_tree::InsertBehavior::*;
167    ///
168    /// let mut tree: Tree<i32> = Tree::new();
169    ///
170    /// tree.insert(Node::new(5), AsRoot).unwrap();
171    /// ```
172    AsRoot,
173
174    ///
175    /// Returns a `Result` containing the `NodeId` of the child that was added or a `NodeIdError` if
176    /// one occurred.
177    ///
178    /// Note: Adds the new Node to the end of its children.
179    ///
180    /// ```
181    /// use id_tree::*;
182    /// use id_tree::InsertBehavior::*;
183    ///
184    /// let root_node = Node::new(1);
185    /// let child_node = Node::new(2);
186    ///
187    /// let mut tree: Tree<i32> = Tree::new();
188    /// let root_id = tree.insert(root_node, AsRoot).unwrap();
189    ///
190    /// tree.insert(child_node, UnderNode(&root_id)).unwrap();
191    /// ```
192    UnderNode(&'a NodeId),
193}
194
195///
196/// Describes the possible behaviors of the `Tree::swap_nodes` method.
197///
198pub enum SwapBehavior {
199    ///
200    /// Take the children of the `Node`s being swapped with them.  In other words, this swaps the
201    /// `Node`s in question along with their entire sub-tree.  This *does not* affect the
202    /// relationship between the `Node`s being swapped and their children.
203    ///
204    /// If one `Node` is a descendant of the other getting swapped, the former *upper* `Node` is
205    /// attached as the last child of the former *lower* `Node` after the swap. (The *lower* will
206    /// take the *uppers* original position as usual.) The subtree of the former *upper* node is not
207    /// touched except that the *lower* `Node` is moved including all its children.
208    ///
209    /// ```
210    /// use id_tree::*;
211    /// use id_tree::InsertBehavior::*;
212    /// use id_tree::SwapBehavior::*;
213    ///
214    /// let mut tree: Tree<i32> = Tree::new();
215    ///
216    /// let root_id = tree.insert(Node::new(1), AsRoot).unwrap();
217    /// let first_child_id = tree.insert(Node::new(2), UnderNode(&root_id)).unwrap();
218    /// let second_child_id = tree.insert(Node::new(3), UnderNode(&root_id)).unwrap();
219    /// let grandchild_id = tree.insert(Node::new(4), UnderNode(&second_child_id)).unwrap();
220    ///
221    /// tree.swap_nodes(&first_child_id, &grandchild_id, TakeChildren).unwrap();
222    ///
223    /// assert!(tree.get(&second_child_id).unwrap().children().contains(&first_child_id));
224    /// assert!(tree.get(&root_id).unwrap().children().contains(&grandchild_id));
225    /// ```
226    ///
227    TakeChildren,
228
229    ///
230    /// Leave the children of the `Node`s being swapped where they are.  In other words, this only
231    /// swaps the `Node`s themselves.  This *does* affect the relationship between the `Node`s
232    /// being swapped and their children.
233    ///
234    /// Please Note: Because this behavior alters the relationship between the `Node`s being
235    /// swapped and their children, any calls to `children()` that have been cloned will no longer
236    /// point to the children of the `Node` that you might think they do.
237    ///
238    /// ```
239    /// use id_tree::*;
240    /// use id_tree::InsertBehavior::*;
241    /// use id_tree::SwapBehavior::*;
242    ///
243    /// let mut tree: Tree<i32> = Tree::new();
244    ///
245    /// let root_id = tree.insert(Node::new(1), AsRoot).unwrap();
246    /// let first_child_id = tree.insert(Node::new(2), UnderNode(&root_id)).unwrap();
247    /// let second_child_id = tree.insert(Node::new(3), UnderNode(&root_id)).unwrap();
248    /// let grandchild_id = tree.insert(Node::new(4), UnderNode(&second_child_id)).unwrap();
249    ///
250    /// tree.swap_nodes(&first_child_id, &second_child_id, LeaveChildren).unwrap();
251    ///
252    /// assert!(tree.get(&first_child_id).unwrap().children().contains(&grandchild_id));
253    /// assert_eq!(tree.get(&second_child_id).unwrap().children().len(), 0);
254    /// ```
255    ///
256    LeaveChildren,
257
258    ///
259    /// Swap the children of the `Node`s in question only.  This does not swap the `Node`s that are
260    /// specified when calling this method.  This *does* affect the relationship between the
261    /// `Node`s that are specified and their children.
262    ///
263    /// If one `Node` is a descendant of the other getting swapped, the child swapping step will
264    /// take place and then the *lower* `Node` in the swap will be added as the last child of the
265    /// *upper* `Node` in the swap.
266    ///
267    /// Please Note: Because this behavior alters the relationship between the `Node`s being
268    /// swapped and their children, any calls to `children()` that have been cloned will no longer
269    /// point to the children of the `Node` that you think they do.
270    ///
271    /// ```
272    /// use id_tree::*;
273    /// use id_tree::InsertBehavior::*;
274    /// use id_tree::SwapBehavior::*;
275    ///
276    /// let mut tree: Tree<i32> = Tree::new();
277    ///
278    /// let root_id = tree.insert(Node::new(1), AsRoot).unwrap();
279    /// let first_child_id = tree.insert(Node::new(2), UnderNode(&root_id)).unwrap();
280    /// let second_child_id = tree.insert(Node::new(3), UnderNode(&root_id)).unwrap();
281    /// let grandchild_id = tree.insert(Node::new(4), UnderNode(&second_child_id)).unwrap();
282    /// let grandchild_id_2 = tree.insert(Node::new(5), UnderNode(&first_child_id)).unwrap();
283    ///
284    /// tree.swap_nodes(&first_child_id, &second_child_id, ChildrenOnly).unwrap();
285    ///
286    /// assert!(tree.get(&first_child_id).unwrap().children().contains(&grandchild_id));
287    /// assert!(tree.get(&second_child_id).unwrap().children().contains(&grandchild_id_2));
288    /// ```
289    ///
290    ChildrenOnly,
291}