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