├── .codecov.yml ├── .editorconfig ├── .github ├── dependabot.yml ├── grcov.yml └── workflows │ └── test.yml ├── .gitignore ├── .rustfmt.toml ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── indextree-macros ├── Cargo.toml ├── LICENSE ├── src │ └── lib.rs └── tests │ ├── regular_usage.rs │ └── stress_test.rs └── indextree ├── Cargo.toml ├── LICENSE ├── examples ├── parallel_iteration.rs ├── simple.rs └── tree-macro.rs ├── src ├── arena.rs ├── debug_pretty_print.rs ├── error.rs ├── id.rs ├── lib.rs ├── node.rs ├── relations.rs ├── siblings_range.rs └── traverse.rs └── tests ├── debug_pretty_print.rs ├── insert-error.rs ├── lib.rs └── remove.rs /.codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | codecov: 3 | notify: 4 | after_n_builds: 1 5 | require_ci_to_pass: false 6 | 7 | coverage: 8 | precision: 1 9 | round: down 10 | range: 50..75 11 | 12 | status: 13 | project: true 14 | patch: false 15 | changes: false 16 | 17 | comment: 18 | layout: "header, diff" 19 | behavior: default 20 | require_changes: false 21 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "11:00" 8 | open-pull-requests-limit: 10 9 | allow: 10 | - dependency-type: direct 11 | - dependency-type: indirect 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: daily 16 | open-pull-requests-limit: 10 17 | -------------------------------------------------------------------------------- /.github/grcov.yml: -------------------------------------------------------------------------------- 1 | branch: true 2 | ignore-not-existing: true 3 | llvm: true 4 | filter: covered 5 | output-type: lcov 6 | output-path: ./lcov.info 7 | prefix-dir: /home/user/build/ 8 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - main 8 | pull_request: 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 14 | - uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 15 | with: 16 | toolchain: stable 17 | - run: cargo generate-lockfile 18 | - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 19 | with: 20 | path: | 21 | target 22 | ~/.cargo/registry 23 | key: rust-build-${{ hashFiles('**/Cargo.lock') }} 24 | restore-keys: rust-build- 25 | - run: make 26 | 27 | rustfmt: 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 31 | - uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 32 | with: 33 | toolchain: stable 34 | components: rustfmt 35 | - run: cargo generate-lockfile 36 | - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 37 | with: 38 | path: | 39 | target 40 | ~/.cargo/registry 41 | key: rust-lint-rustfmt-${{ hashFiles('**/Cargo.lock') }} 42 | restore-keys: rust-lint-rustfmt- 43 | - run: make lint-rustfmt 44 | 45 | clippy: 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 49 | - uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 50 | with: 51 | toolchain: stable 52 | components: clippy 53 | - run: cargo generate-lockfile 54 | - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 55 | with: 56 | path: | 57 | target 58 | ~/.cargo/registry 59 | key: rust-lint-clippy-${{ hashFiles('**/Cargo.lock') }} 60 | restore-keys: rust-lint-clippy- 61 | - run: make lint-clippy 62 | 63 | unit: 64 | runs-on: ubuntu-latest 65 | steps: 66 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 67 | - uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 68 | with: 69 | toolchain: stable 70 | - run: cargo generate-lockfile 71 | - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 72 | with: 73 | path: | 74 | target 75 | ~/.cargo/registry 76 | key: rust-test-${{ hashFiles('**/Cargo.lock') }} 77 | restore-keys: rust-test- 78 | - run: make test 79 | 80 | coverage: 81 | runs-on: ubuntu-latest 82 | steps: 83 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 84 | - uses: taiki-e/install-action@cargo-llvm-cov 85 | - run: cargo llvm-cov --all-features --lcov --output-path lcov.info 86 | - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 87 | with: 88 | files: lcov.info 89 | 90 | doc: 91 | runs-on: ubuntu-latest 92 | steps: 93 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 94 | - uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203 95 | with: 96 | toolchain: stable 97 | - run: cargo generate-lockfile 98 | - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 99 | with: 100 | path: | 101 | target 102 | ~/.cargo/registry 103 | key: rust-doc-${{ hashFiles('**/Cargo.lock') }} 104 | restore-keys: rust-doc- 105 | - run: make build-doc 106 | - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 107 | with: 108 | name: docs 109 | path: target/doc 110 | 111 | doc-publish: 112 | if: github.ref == 'refs/heads/main' 113 | needs: doc 114 | runs-on: ubuntu-latest 115 | steps: 116 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 117 | with: 118 | fetch-depth: 0 119 | token: ${{ secrets.GH_TOKEN }} 120 | - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 121 | with: 122 | name: docs 123 | path: target/doc 124 | - name: Update gh-pages branch 125 | run: | 126 | git config --global user.email mail@saschagrunert.de 127 | git config --global user.name "CircleCI" 128 | git fetch origin gh-pages 129 | git checkout -f gh-pages 130 | rm -rf doc 131 | mv target/doc . 132 | git add . 133 | git diff-index --quiet HEAD || git commit -m 'Update documentation' 134 | git push -f origin gh-pages 135 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | Cargo.lock 5 | 6 | # swap 7 | [._]*.s[a-w][a-z] 8 | [._]s[a-w][a-z] 9 | # session 10 | Session.vim 11 | # temporary 12 | .netrwhist 13 | *~ 14 | # auto-generated tag files 15 | tags 16 | # backup files from cargo fmt 17 | *.bk 18 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 100 2 | hard_tabs = false 3 | tab_spaces = 4 4 | newline_style = "Auto" 5 | use_small_heuristics = "Default" 6 | indent_style = "Block" 7 | wrap_comments = false 8 | format_code_in_doc_comments = false 9 | comment_width = 80 10 | normalize_comments = false 11 | normalize_doc_attributes = false 12 | license_template_path = "" 13 | format_strings = false 14 | format_macro_matchers = false 15 | format_macro_bodies = true 16 | empty_item_single_line = true 17 | struct_lit_single_line = true 18 | fn_single_line = false 19 | where_single_line = false 20 | imports_indent = "Block" 21 | imports_layout = "Mixed" 22 | imports_granularity = "Preserve" 23 | group_imports = "Preserve" 24 | reorder_imports = true 25 | reorder_modules = true 26 | reorder_impl_items = false 27 | type_punctuation_density = "Wide" 28 | space_before_colon = false 29 | space_after_colon = true 30 | spaces_around_ranges = false 31 | binop_separator = "Front" 32 | remove_nested_parens = true 33 | combine_control_expr = true 34 | overflow_delimited_expr = false 35 | struct_field_align_threshold = 0 36 | enum_discrim_align_threshold = 0 37 | match_arm_blocks = true 38 | match_arm_leading_pipes = "Never" 39 | force_multiline_blocks = false 40 | fn_args_layout = "Tall" 41 | brace_style = "SameLineWhere" 42 | control_brace_style = "AlwaysSameLine" 43 | trailing_semicolon = true 44 | trailing_comma = "Vertical" 45 | match_block_trailing_comma = false 46 | blank_lines_upper_bound = 1 47 | blank_lines_lower_bound = 0 48 | edition = "2015" 49 | version = "One" 50 | inline_attribute_width = 0 51 | merge_derives = true 52 | use_try_shorthand = false 53 | use_field_init_shorthand = false 54 | force_explicit_abi = true 55 | condense_wildcard_suffixes = false 56 | color = "Auto" 57 | unstable_features = false 58 | disable_all_formatting = false 59 | skip_children = false 60 | hide_parse_errors = false 61 | error_on_line_overflow = false 62 | error_on_unformatted = false 63 | report_todo = "Never" 64 | report_fixme = "Never" 65 | ignore = [] 66 | emit_mode = "Files" 67 | make_backup = false 68 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "indextree", 5 | "indextree-macros", 6 | ] 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sascha Grunert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GENERAL_ARGS = --release 2 | 3 | .PHONY: \ 4 | build \ 5 | build-doc \ 6 | lint-rustfmt \ 7 | lint-clippy \ 8 | test 9 | 10 | ifndef VERBOSE 11 | .SILENT: 12 | else 13 | GENERAL_ARGS += -v 14 | endif 15 | 16 | all: build 17 | 18 | build: 19 | cargo build $(GENERAL_ARGS) 20 | 21 | build-doc: 22 | cargo doc --all --no-deps 23 | 24 | lint-clippy: 25 | cargo clippy --all-targets -- -D warnings 26 | 27 | lint-rustfmt: 28 | cargo fmt --version 29 | cargo fmt 30 | git diff --exit-code 31 | 32 | test: 33 | cargo test --features="par_iter" 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # indextree 2 | 3 | [![GitHub Actions](https://github.com/saschagrunert/indextree/actions/workflows/test.yml/badge.svg)](https://github.com/saschagrunert/indextree/actions/workflows/test.yml) 4 | [![Coverage](https://codecov.io/gh/saschagrunert/indextree/branch/main/graph/badge.svg)](https://codecov.io/gh/saschagrunert/indextree) 5 | [![Dependency Status](https://deps.rs/repo/github/saschagrunert/indextree/status.svg)](https://deps.rs/repo/github/saschagrunert/indextree) 6 | [![Doc indextree](https://img.shields.io/badge/main-indextree-blue.svg)](https://saschagrunert.github.io/indextree/doc/indextree) 7 | [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/saschagrunert/indextree/blob/main/LICENSE) 8 | [![Crates.io](https://img.shields.io/crates/v/indextree.svg)](https://crates.io/crates/indextree) 9 | [![doc.rs](https://docs.rs/indextree/badge.svg)](https://docs.rs/indextree) 10 | 11 | ## Arena based tree structure with multithreading support 12 | 13 | This arena tree structure is using just a single `Vec` and numerical identifiers 14 | (indices in the vector) instead of reference counted pointers. This means there 15 | is no `RefCell` and mutability is handled in a way much more idiomatic to Rust 16 | through unique (&mut) access to the arena. The tree can be sent or shared across 17 | threads like a `Vec`. This enables general multiprocessing support like 18 | parallel tree traversals. 19 | 20 | ### Example usage 21 | 22 | ```rust 23 | use indextree::Arena; 24 | 25 | // Create a new arena 26 | let arena = &mut Arena::new(); 27 | 28 | // Add some new nodes to the arena 29 | let a = arena.new_node(1); 30 | let b = arena.new_node(2); 31 | 32 | // Append a to b 33 | assert!(a.append(b, arena).is_ok()); 34 | assert_eq!(b.ancestors(arena).into_iter().count(), 2); 35 | ``` 36 | 37 | ### Benchmarks 38 | 39 | https://github.com/mooman219/generational_arena_bench 40 | -------------------------------------------------------------------------------- /indextree-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "indextree-macros" 3 | version = "0.1.3" 4 | edition = "2021" 5 | description = "Macros for indextree" 6 | license = "MIT" 7 | 8 | [lib] 9 | proc-macro = true 10 | 11 | [dependencies] 12 | proc-macro2 = "1.0.95" 13 | quote = "1.0.40" 14 | thiserror = "2.0.12" 15 | either = "1.15.0" 16 | syn = { version = "2.0.101", features = ["extra-traits", "full", "visit"] } 17 | itertools = "0.14.0" 18 | strum = { version = "0.27.1", features = ["derive"] } 19 | 20 | [dev-dependencies] 21 | indextree = { path = "../indextree", version = "4.7.4" } 22 | -------------------------------------------------------------------------------- /indextree-macros/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /indextree-macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | use either::Either; 2 | use itertools::Itertools; 3 | use proc_macro2::TokenStream; 4 | use quote::{quote, ToTokens}; 5 | use strum::EnumDiscriminants; 6 | use syn::{ 7 | braced, 8 | parse::{Parse, ParseStream}, 9 | parse_macro_input, 10 | punctuated::Punctuated, 11 | Expr, Token, 12 | }; 13 | 14 | #[derive(Clone, Debug)] 15 | struct IndexNode { 16 | node: Expr, 17 | children: Punctuated, 18 | } 19 | 20 | impl Parse for IndexNode { 21 | fn parse(input: ParseStream) -> syn::Result { 22 | let node = input.parse::()?; 23 | 24 | if input.parse::]>().is_err() { 25 | return Ok(IndexNode { 26 | node, 27 | children: Punctuated::new(), 28 | }); 29 | } 30 | 31 | let children_stream; 32 | braced!(children_stream in input); 33 | let children = children_stream.parse_terminated(Self::parse, Token![,])?; 34 | 35 | Ok(IndexNode { node, children }) 36 | } 37 | } 38 | 39 | #[derive(Clone, Debug)] 40 | struct IndexTree { 41 | arena: Expr, 42 | root_node: Expr, 43 | nodes: Punctuated, 44 | } 45 | 46 | impl Parse for IndexTree { 47 | fn parse(input: ParseStream) -> syn::Result { 48 | let arena = input.parse::()?; 49 | 50 | input.parse::()?; 51 | 52 | let root_node = input.parse::()?; 53 | 54 | let nodes = if input.parse::]>().is_ok() { 55 | let braced_nodes; 56 | braced!(braced_nodes in input); 57 | braced_nodes.parse_terminated(IndexNode::parse, Token![,])? 58 | } else { 59 | Punctuated::new() 60 | }; 61 | 62 | let _ = input.parse::(); 63 | 64 | Ok(IndexTree { 65 | arena, 66 | root_node, 67 | nodes, 68 | }) 69 | } 70 | } 71 | 72 | #[derive(Clone, EnumDiscriminants, Debug)] 73 | #[strum_discriminants(name(ActionKind))] 74 | enum Action { 75 | Append(Expr), 76 | Parent, 77 | Nest, 78 | } 79 | 80 | impl ToTokens for Action { 81 | fn to_tokens(&self, tokens: &mut TokenStream) { 82 | tokens.extend(self.to_stream()) 83 | } 84 | } 85 | 86 | impl Action { 87 | fn to_stream(&self) -> TokenStream { 88 | match self { 89 | Action::Append(expr) => quote! { 90 | __last = __node.append_value(#expr, __arena); 91 | }, 92 | Action::Parent => quote! { 93 | let __temp = ::indextree::Arena::get(__arena, __node); 94 | let __temp = ::core::option::Option::unwrap(__temp); 95 | let __temp = ::indextree::Node::parent(__temp); 96 | let __temp = ::core::option::Option::unwrap(__temp); 97 | __node = __temp; 98 | }, 99 | Action::Nest => quote! { 100 | __node = __last; 101 | }, 102 | } 103 | } 104 | } 105 | 106 | #[derive(Clone, Debug)] 107 | struct NestingLevelMarker; 108 | 109 | #[derive(Clone, Debug)] 110 | struct ActionStream { 111 | count: usize, 112 | kind: ActionKind, 113 | stream: TokenStream, 114 | } 115 | 116 | impl ToTokens for ActionStream { 117 | fn to_tokens(&self, tokens: &mut TokenStream) { 118 | tokens.extend(self.stream.clone()); 119 | } 120 | } 121 | 122 | /// Construct a tree for a given arena. 123 | /// 124 | /// This macro creates a tree in an [`Arena`] with a pre-defined layout. If the root node is of 125 | /// type [`NodeId`], then that [`NodeId`] is used for the root node, but if it's any other type, 126 | /// then it creates a new root node on-the-fly. The macro returns [`NodeId`] of the root node. 127 | /// 128 | /// # Examples 129 | /// 130 | /// ``` 131 | /// # use indextree::{Arena, macros::tree}; 132 | /// # let mut arena = Arena::new(); 133 | /// let root_node = arena.new_node("root node"); 134 | /// tree!( 135 | /// &mut arena, 136 | /// root_node => { 137 | /// "1", 138 | /// "2" => { 139 | /// "2_1" => { "2_1_1" }, 140 | /// "2_2", 141 | /// }, 142 | /// "3", 143 | /// } 144 | /// ); 145 | /// 146 | /// let automagical_root_node = tree!( 147 | /// &mut arena, 148 | /// "root node, but automagically created" => { 149 | /// "1", 150 | /// "2" => { 151 | /// "2_1" => { "2_1_1" }, 152 | /// "2_2", 153 | /// }, 154 | /// "3", 155 | /// } 156 | /// ); 157 | /// ``` 158 | /// 159 | /// Note that you can anchor the root node in the macro to any node at any nesting. So you can take 160 | /// an already existing node of a tree and attach another tree to it: 161 | /// ``` 162 | /// # use indextree::{Arena, macros::tree}; 163 | /// # let mut arena = Arena::new(); 164 | /// let root_node = tree!( 165 | /// &mut arena, 166 | /// "root node" => { 167 | /// "1", 168 | /// "2", 169 | /// "3", 170 | /// } 171 | /// ); 172 | /// 173 | /// let node_1 = arena.get(root_node).unwrap().first_child().unwrap(); 174 | /// let node_2 = arena.get(node_1).unwrap().next_sibling().unwrap(); 175 | /// tree!( 176 | /// &mut arena, 177 | /// node_2 => { 178 | /// "2_1" => { "2_1_1" }, 179 | /// "2_2", 180 | /// } 181 | /// ); 182 | /// ``` 183 | /// 184 | /// It is also possible to create an empty root_node, although, I'm not sure why you'd want to do 185 | /// that. 186 | /// ``` 187 | /// # use indextree::{Arena, macros::tree}; 188 | /// # let mut arena = Arena::new(); 189 | /// let root_node = tree!( 190 | /// &mut arena, 191 | /// "my root node", 192 | /// ); 193 | /// ``` 194 | /// Empty nodes can also be defined as `=> {}` 195 | /// ``` 196 | /// # use indextree::{Arena, macros::tree}; 197 | /// # let mut arena = Arena::new(); 198 | /// let root_node = tree!( 199 | /// &mut arena, 200 | /// "my root node" => {}, 201 | /// ); 202 | /// ``` 203 | /// 204 | /// [`Arena`]: https://docs.rs/indextree/latest/indextree/struct.Arena.html 205 | /// [`NodeId`]: https://docs.rs/indextree/latest/indextree/struct.NodeId.html 206 | #[proc_macro] 207 | pub fn tree(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 208 | let IndexTree { 209 | arena, 210 | root_node, 211 | nodes, 212 | } = parse_macro_input!(input as IndexTree); 213 | 214 | let mut stack: Vec> = 215 | nodes.into_iter().map(Either::Left).rev().collect(); 216 | 217 | let mut action_buffer: Vec = Vec::new(); 218 | 219 | while let Some(item) = stack.pop() { 220 | let Either::Left(IndexNode { node, children }) = item else { 221 | action_buffer.push(Action::Parent); 222 | continue; 223 | }; 224 | 225 | action_buffer.push(Action::Append(node)); 226 | 227 | if children.is_empty() { 228 | continue; 229 | } 230 | 231 | // going one level deeper 232 | stack.push(Either::Right(NestingLevelMarker)); 233 | action_buffer.push(Action::Nest); 234 | stack.extend(children.into_iter().map(Either::Left).rev()); 235 | } 236 | 237 | let mut actions: Vec = action_buffer 238 | .into_iter() 239 | .map(|action| ActionStream { 240 | count: 1, 241 | kind: ActionKind::from(&action), 242 | stream: action.to_stream(), 243 | }) 244 | .coalesce(|action1, action2| { 245 | if action1.kind != action2.kind { 246 | return Err((action1, action2)); 247 | } 248 | 249 | let count = action1.count + action2.count; 250 | let kind = action1.kind; 251 | let mut stream = action1.stream; 252 | stream.extend(action2.stream); 253 | Ok(ActionStream { 254 | count, 255 | kind, 256 | stream, 257 | }) 258 | }) 259 | .collect(); 260 | 261 | let is_last_action_useless = actions 262 | .last() 263 | .map(|last| last.kind == ActionKind::Parent) 264 | .unwrap_or(false); 265 | if is_last_action_useless { 266 | actions.pop(); 267 | } 268 | 269 | // HACK(alexmozaidze): Due to the fact that specialization is unstable, we must resort to 270 | // autoref specialization trick. 271 | // https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md 272 | quote! {{ 273 | let mut __arena: &mut ::indextree::Arena<_> = #arena; 274 | 275 | #[repr(transparent)] 276 | struct __Wrapping<__T>(::core::mem::ManuallyDrop<__T>); 277 | 278 | trait __ToNodeId<__T> { 279 | fn __to_node_id(&mut self, __arena: &mut ::indextree::Arena<__T>) -> ::indextree::NodeId; 280 | } 281 | 282 | trait __NodeIdToNodeId<__T> { 283 | fn __to_node_id(&mut self, __arena: &mut ::indextree::Arena<__T>) -> ::indextree::NodeId; 284 | } 285 | 286 | impl<__T> __NodeIdToNodeId<__T> for __Wrapping<::indextree::NodeId> { 287 | fn __to_node_id(&mut self, __arena: &mut ::indextree::Arena<__T>) -> ::indextree::NodeId { 288 | unsafe { ::core::mem::ManuallyDrop::take(&mut self.0) } 289 | } 290 | } 291 | 292 | impl<__T> __ToNodeId<__T> for &mut __Wrapping<__T> { 293 | fn __to_node_id(&mut self, __arena: &mut ::indextree::Arena<__T>) -> ::indextree::NodeId { 294 | ::indextree::Arena::new_node(__arena, unsafe { ::core::mem::ManuallyDrop::take(&mut self.0) }) 295 | } 296 | } 297 | 298 | let __root_node: ::indextree::NodeId = { 299 | let mut __root_node = __Wrapping(::core::mem::ManuallyDrop::new(#root_node)); 300 | (&mut __root_node).__to_node_id(__arena) 301 | }; 302 | let mut __node: ::indextree::NodeId = __root_node; 303 | let mut __last: ::indextree::NodeId; 304 | 305 | #(#actions)* 306 | 307 | __root_node 308 | }}.into() 309 | } 310 | -------------------------------------------------------------------------------- /indextree-macros/tests/regular_usage.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{Debug, Display}; 2 | 3 | use indextree::{Arena, NodeId}; 4 | use indextree_macros::tree; 5 | 6 | pub fn compare_nodes(arena: &Arena, n1: NodeId, n2: NodeId) 7 | where 8 | T: Debug + Display + Clone + PartialEq, 9 | { 10 | let get_val = |id: NodeId| -> T { arena.get(id).unwrap().get().clone() }; 11 | 12 | let n1_iter = n1.descendants(arena).skip(1).map(get_val); 13 | let n2_iter = n2.descendants(arena).skip(1).map(get_val); 14 | 15 | assert!( 16 | Iterator::eq(n1_iter, n2_iter), 17 | r#"Tree equality assertion failed! 18 | 19 | ### Left Tree ### 20 | 21 | {} 22 | 23 | ### Right Tree ### 24 | 25 | {}"#, 26 | n1.debug_pretty_print(arena), 27 | n2.debug_pretty_print(arena), 28 | ); 29 | } 30 | 31 | #[test] 32 | fn no_nesting() { 33 | let mut arena = Arena::new(); 34 | 35 | let root_macro = tree! { 36 | &mut arena, 37 | "macro root node" => { 38 | "1", 39 | "2", 40 | "3", 41 | "4", 42 | "5", 43 | "6", 44 | "7", 45 | "8", 46 | "9", 47 | "10", 48 | } 49 | }; 50 | 51 | let root_proc = arena.new_node("procedural root node"); 52 | root_proc.append_value("1", &mut arena); 53 | root_proc.append_value("2", &mut arena); 54 | root_proc.append_value("3", &mut arena); 55 | root_proc.append_value("4", &mut arena); 56 | root_proc.append_value("5", &mut arena); 57 | root_proc.append_value("6", &mut arena); 58 | root_proc.append_value("7", &mut arena); 59 | root_proc.append_value("8", &mut arena); 60 | root_proc.append_value("9", &mut arena); 61 | root_proc.append_value("10", &mut arena); 62 | 63 | compare_nodes(&arena, root_proc, root_macro); 64 | } 65 | 66 | #[test] 67 | fn mild_nesting() { 68 | let mut arena = Arena::new(); 69 | 70 | let root_macro = arena.new_node("macro root node"); 71 | tree!( 72 | &mut arena, 73 | root_macro => { 74 | "1", 75 | "2" => { 76 | "2_1" => { "2_1_1" }, 77 | "2_2", 78 | }, 79 | "3", 80 | } 81 | ); 82 | 83 | let root_proc = arena.new_node("proc root node"); 84 | root_proc.append_value("1", &mut arena); 85 | let node_2 = root_proc.append_value("2", &mut arena); 86 | let node_2_1 = node_2.append_value("2_1", &mut arena); 87 | node_2_1.append_value("2_1_1", &mut arena); 88 | node_2.append_value("2_2", &mut arena); 89 | root_proc.append_value("3", &mut arena); 90 | 91 | compare_nodes(&arena, root_proc, root_macro); 92 | } 93 | -------------------------------------------------------------------------------- /indextree-macros/tests/stress_test.rs: -------------------------------------------------------------------------------- 1 | mod regular_usage; 2 | 3 | use indextree::Arena; 4 | use indextree_macros::tree; 5 | use regular_usage::compare_nodes; 6 | 7 | #[test] 8 | fn outragous_nesting() { 9 | let mut arena = Arena::new(); 10 | 11 | let root_macro = tree!(&mut arena, "macro root node"); 12 | tree!( 13 | &mut arena, 14 | root_macro => { 15 | "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"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 16 | } 17 | ); 18 | 19 | let root_proc = arena.new_node("proc root node"); 20 | let mut deepest_node = root_proc.append_value("1", &mut arena); 21 | let owned_strings: Vec = (2..=100).map(|x| x.to_string()).collect(); 22 | for i in &owned_strings { 23 | deepest_node = deepest_node.append_value(i.as_str(), &mut arena); 24 | } 25 | 26 | compare_nodes(&arena, root_macro, root_proc); 27 | } 28 | 29 | #[test] 30 | fn very_long() { 31 | let mut arena = Arena::new(); 32 | 33 | let root_macro = tree!( 34 | &mut arena, 35 | "macro root node" => { 36 | "1", 37 | "2", 38 | "3", 39 | "4", 40 | "5", 41 | "6", 42 | "7", 43 | "8", 44 | "9", 45 | "10", 46 | "11", 47 | "12", 48 | "13", 49 | "14", 50 | "15", 51 | "16", 52 | "17", 53 | "18", 54 | "19", 55 | "20", 56 | "21", 57 | "22", 58 | "23", 59 | "24", 60 | "25", 61 | "26", 62 | "27", 63 | "28", 64 | "29", 65 | "30", 66 | "31", 67 | "32", 68 | "33", 69 | "34", 70 | "35", 71 | "36", 72 | "37", 73 | "38", 74 | "39", 75 | "40", 76 | "41", 77 | "42", 78 | "43", 79 | "44", 80 | "45", 81 | "46", 82 | "47", 83 | "48", 84 | "49", 85 | "50", 86 | "51", 87 | "52", 88 | "53", 89 | "54", 90 | "55", 91 | "56", 92 | "57", 93 | "58", 94 | "59", 95 | "60", 96 | "61", 97 | "62", 98 | "63", 99 | "64", 100 | "65", 101 | "66", 102 | "67", 103 | "68", 104 | "69", 105 | "70", 106 | "71", 107 | "72", 108 | "73", 109 | "74", 110 | "75", 111 | "76", 112 | "77", 113 | "78", 114 | "79", 115 | "80", 116 | "81", 117 | "82", 118 | "83", 119 | "84", 120 | "85", 121 | "86", 122 | "87", 123 | "88", 124 | "89", 125 | "90", 126 | "91", 127 | "92", 128 | "93", 129 | "94", 130 | "95", 131 | "96", 132 | "97", 133 | "98", 134 | "99", 135 | "100", 136 | } 137 | ); 138 | 139 | let root_proc = arena.new_node("proc root node"); 140 | let owned_strings: Vec = (1..=100).map(|x| x.to_string()).collect(); 141 | for i in &owned_strings { 142 | root_proc.append_value(i.as_str(), &mut arena); 143 | } 144 | 145 | compare_nodes(&arena, root_macro, root_proc); 146 | } 147 | -------------------------------------------------------------------------------- /indextree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "indextree" 3 | version = "4.7.4" 4 | license = "MIT" 5 | readme = "../README.md" 6 | keywords = ["tree", "arena", "index", "indextree", "trie"] 7 | authors = ["Sascha Grunert "] 8 | repository = "https://github.com/saschagrunert/indextree" 9 | homepage = "https://github.com/saschagrunert/indextree" 10 | documentation = "https://docs.rs/indextree" 11 | description = "Arena based tree structure by using indices instead of reference counted pointers" 12 | categories = ["data-structures"] 13 | edition = "2021" 14 | 15 | [features] 16 | default = ["std", "macros"] 17 | deser = ["serde"] 18 | par_iter = ["rayon"] 19 | std = [] 20 | macros = ["indextree-macros"] 21 | 22 | [dependencies] 23 | rayon = { version = "1.10.0", optional = true } 24 | serde = { version = "1.0.219", features = ["derive"], optional = true } 25 | indextree-macros = { path = "../indextree-macros", version = "0.1.3", optional = true } 26 | 27 | [[example]] 28 | name = "parallel_iteration" 29 | required-features = ["par_iter"] 30 | 31 | [[example]] 32 | name = "simple" 33 | 34 | [[example]] 35 | name = "tree-macro" 36 | required-features = ["macros"] 37 | -------------------------------------------------------------------------------- /indextree/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /indextree/examples/parallel_iteration.rs: -------------------------------------------------------------------------------- 1 | use indextree::*; 2 | use rayon::prelude::*; 3 | 4 | pub fn main() { 5 | // Create a new arena 6 | let arena = &mut Arena::new(); 7 | 8 | // Add some new nodes to the arena 9 | println!("Creating arena tree"); 10 | let mut last_node = arena.new_node(1); 11 | for i in 1..10_000_000 { 12 | let node = arena.new_node(i); 13 | node.append(last_node, arena); 14 | last_node = node; 15 | } 16 | 17 | println!("Parallel iteration over arena tree"); 18 | let _: Vec = arena 19 | .par_iter() 20 | .map(|ref mut i| (*i.get() as f64).sqrt()) 21 | .collect(); 22 | } 23 | -------------------------------------------------------------------------------- /indextree/examples/simple.rs: -------------------------------------------------------------------------------- 1 | use indextree::Arena; 2 | 3 | pub fn main() { 4 | // Create a new arena 5 | let arena = &mut Arena::new(); 6 | 7 | // Add some new nodes to the arena 8 | let a = arena.new_node(1); 9 | let b = arena.new_node(2); 10 | 11 | // Append a to b 12 | a.append(b, arena); 13 | assert_eq!(b.ancestors(arena).count(), 2); 14 | } 15 | -------------------------------------------------------------------------------- /indextree/examples/tree-macro.rs: -------------------------------------------------------------------------------- 1 | use indextree::{macros::tree, Arena}; 2 | 3 | fn main() { 4 | let mut arena = Arena::new(); 5 | 6 | // It works with existing nodes 7 | let root_node = arena.new_node("my root node"); 8 | tree!( 9 | &mut arena, 10 | root_node => { 11 | "1", 12 | "2" => { 13 | "2_1" => { "2_1_1" }, 14 | "2_2", 15 | }, 16 | "3" => {}, 17 | } 18 | ); 19 | 20 | println!("{}", root_node.debug_pretty_print(&arena)); 21 | 22 | // It can also create a root node for you! 23 | let root_node = tree!( 24 | &mut arena, 25 | "my root node, but automagically created" => { 26 | "1", 27 | "2" => { 28 | "2_1" => { "2_1_1" }, 29 | "2_2", 30 | }, 31 | "3", 32 | } 33 | ); 34 | 35 | println!("{}", root_node.debug_pretty_print(&arena)); 36 | } 37 | -------------------------------------------------------------------------------- /indextree/src/arena.rs: -------------------------------------------------------------------------------- 1 | //! Arena. 2 | 3 | #[cfg(not(feature = "std"))] 4 | use alloc::vec::Vec; 5 | 6 | #[cfg(not(feature = "std"))] 7 | use core::{ 8 | mem, 9 | num::NonZeroUsize, 10 | ops::{Index, IndexMut}, 11 | slice, 12 | }; 13 | 14 | #[cfg(feature = "par_iter")] 15 | use rayon::prelude::*; 16 | 17 | #[cfg(feature = "deser")] 18 | use serde::{Deserialize, Serialize}; 19 | 20 | #[cfg(feature = "std")] 21 | use std::{ 22 | mem, 23 | num::NonZeroUsize, 24 | ops::{Index, IndexMut}, 25 | slice, 26 | }; 27 | 28 | use crate::{node::NodeData, Node, NodeId}; 29 | 30 | #[derive(PartialEq, Eq, Clone, Debug)] 31 | #[cfg_attr(feature = "deser", derive(Deserialize, Serialize))] 32 | /// An `Arena` structure containing certain [`Node`]s. 33 | /// 34 | /// [`Node`]: struct.Node.html 35 | pub struct Arena { 36 | nodes: Vec>, 37 | first_free_slot: Option, 38 | last_free_slot: Option, 39 | } 40 | 41 | impl Arena { 42 | /// Creates a new empty `Arena`. 43 | pub fn new() -> Arena { 44 | Self::default() 45 | } 46 | 47 | /// Creates a new empty `Arena` with enough capacity to store `n` nodes. 48 | pub fn with_capacity(n: usize) -> Self { 49 | Self { 50 | nodes: Vec::with_capacity(n), 51 | first_free_slot: None, 52 | last_free_slot: None, 53 | } 54 | } 55 | 56 | /// Returns the number of nodes the arena can hold without reallocating. 57 | pub fn capacity(&self) -> usize { 58 | self.nodes.capacity() 59 | } 60 | 61 | /// Reserves capacity for `additional` more nodes to be inserted. 62 | /// 63 | /// The arena may reserve more space to avoid frequent reallocations. 64 | /// 65 | /// # Panics 66 | /// 67 | /// Panics if the new capacity exceeds isize::MAX bytes. 68 | pub fn reserve(&mut self, additional: usize) { 69 | self.nodes.reserve(additional); 70 | } 71 | 72 | /// Retrieves the `NodeId` corresponding to a `Node` in the `Arena`. 73 | /// 74 | /// # Examples 75 | /// 76 | /// ``` 77 | /// # use indextree::Arena; 78 | /// let mut arena = Arena::new(); 79 | /// let foo = arena.new_node("foo"); 80 | /// let node = arena.get(foo).unwrap(); 81 | /// 82 | /// let node_id = arena.get_node_id(node).unwrap(); 83 | /// assert_eq!(*arena[node_id].get(), "foo"); 84 | /// ``` 85 | pub fn get_node_id(&self, node: &Node) -> Option { 86 | let nodes_range = self.nodes.as_ptr_range(); 87 | let p = node as *const Node; 88 | 89 | if !nodes_range.contains(&p) { 90 | return None; 91 | } 92 | 93 | let node_index = (p as usize - nodes_range.start as usize) / mem::size_of::>(); 94 | let node_id = NonZeroUsize::new(node_index.wrapping_add(1))?; 95 | 96 | Some(NodeId::from_non_zero_usize( 97 | node_id, 98 | self.nodes[node_index].stamp, 99 | )) 100 | } 101 | 102 | /// Retrieves the `NodeId` corresponding to the `Node` at `index` in the `Arena`, if it exists. 103 | /// 104 | /// Note: We use 1 based indexing, so the first element is at `1` and not `0`. 105 | /// 106 | /// # Examples 107 | /// 108 | /// ``` 109 | /// # use indextree::Arena; 110 | /// # use std::num::NonZeroUsize; 111 | /// let mut arena = Arena::new(); 112 | /// let foo = arena.new_node("foo"); 113 | /// let node = arena.get(foo).unwrap(); 114 | /// let index: NonZeroUsize = foo.into(); 115 | /// 116 | /// let new_foo = arena.get_node_id_at(index).unwrap(); 117 | /// assert_eq!(foo, new_foo); 118 | /// 119 | /// foo.remove(&mut arena); 120 | /// let new_foo = arena.get_node_id_at(index); 121 | /// assert!(new_foo.is_none(), "must be none if the node at the index doesn't exist"); 122 | /// ``` 123 | pub fn get_node_id_at(&self, index: NonZeroUsize) -> Option { 124 | let index0 = index.get() - 1; // we use 1 based indexing. 125 | self.nodes 126 | .get(index0) 127 | .filter(|n| !n.is_removed()) 128 | .map(|node| NodeId::from_non_zero_usize(index, node.stamp)) 129 | } 130 | 131 | /// Creates a new node from its associated data. 132 | /// 133 | /// # Panics 134 | /// 135 | /// Panics if the arena already has `usize::max_value()` nodes. 136 | /// 137 | /// # Examples 138 | /// 139 | /// ``` 140 | /// # use indextree::Arena; 141 | /// let mut arena = Arena::new(); 142 | /// let foo = arena.new_node("foo"); 143 | /// 144 | /// assert_eq!(*arena[foo].get(), "foo"); 145 | /// ``` 146 | pub fn new_node(&mut self, data: T) -> NodeId { 147 | let (index, stamp) = if let Some(index) = self.pop_front_free_node() { 148 | let node = &mut self.nodes[index]; 149 | node.reuse(data); 150 | (index, node.stamp) 151 | } else { 152 | let index = self.nodes.len(); 153 | let node = Node::new(data); 154 | let stamp = node.stamp; 155 | self.nodes.push(node); 156 | (index, stamp) 157 | }; 158 | let next_index1 = 159 | NonZeroUsize::new(index.wrapping_add(1)).expect("Too many nodes in the arena"); 160 | NodeId::from_non_zero_usize(next_index1, stamp) 161 | } 162 | 163 | /// Counts the number of nodes in arena and returns it. 164 | /// 165 | /// # Examples 166 | /// 167 | /// ``` 168 | /// # use indextree::Arena; 169 | /// let mut arena = Arena::new(); 170 | /// let foo = arena.new_node("foo"); 171 | /// let _bar = arena.new_node("bar"); 172 | /// assert_eq!(arena.count(), 2); 173 | /// 174 | /// foo.remove(&mut arena); 175 | /// assert_eq!(arena.count(), 2); 176 | /// ``` 177 | pub fn count(&self) -> usize { 178 | self.nodes.len() 179 | } 180 | 181 | /// Returns `true` if arena has no nodes, `false` otherwise. 182 | /// 183 | /// # Examples 184 | /// 185 | /// ``` 186 | /// # use indextree::Arena; 187 | /// let mut arena = Arena::new(); 188 | /// assert!(arena.is_empty()); 189 | /// 190 | /// let foo = arena.new_node("foo"); 191 | /// assert!(!arena.is_empty()); 192 | /// 193 | /// foo.remove(&mut arena); 194 | /// assert!(!arena.is_empty()); 195 | /// ``` 196 | pub fn is_empty(&self) -> bool { 197 | self.count() == 0 198 | } 199 | 200 | /// Returns a reference to the node with the given id if in the arena. 201 | /// 202 | /// Returns `None` if not available. 203 | /// 204 | /// # Examples 205 | /// 206 | /// ``` 207 | /// # use indextree::{Arena, NodeId}; 208 | /// let mut arena = Arena::new(); 209 | /// let foo = arena.new_node("foo"); 210 | /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo")); 211 | /// ``` 212 | /// 213 | /// Note that this does not check whether the given node ID is created by 214 | /// the arena. 215 | /// 216 | /// ``` 217 | /// # use indextree::Arena; 218 | /// let mut arena = Arena::new(); 219 | /// let foo = arena.new_node("foo"); 220 | /// let bar = arena.new_node("bar"); 221 | /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo")); 222 | /// 223 | /// let mut another_arena = Arena::new(); 224 | /// let _ = another_arena.new_node("Another arena"); 225 | /// assert_eq!(another_arena.get(foo).map(|node| *node.get()), Some("Another arena")); 226 | /// assert!(another_arena.get(bar).is_none()); 227 | /// ``` 228 | pub fn get(&self, id: NodeId) -> Option<&Node> { 229 | self.nodes.get(id.index0()) 230 | } 231 | 232 | /// Returns a mutable reference to the node with the given id if in the 233 | /// arena. 234 | /// 235 | /// Returns `None` if not available. 236 | /// 237 | /// # Examples 238 | /// 239 | /// ``` 240 | /// # use indextree::{Arena, NodeId}; 241 | /// let mut arena = Arena::new(); 242 | /// let foo = arena.new_node("foo"); 243 | /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo")); 244 | /// 245 | /// *arena.get_mut(foo).expect("The `foo` node exists").get_mut() = "FOO!"; 246 | /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("FOO!")); 247 | /// ``` 248 | pub fn get_mut(&mut self, id: NodeId) -> Option<&mut Node> { 249 | self.nodes.get_mut(id.index0()) 250 | } 251 | 252 | /// Returns an iterator of all nodes in the arena in storage-order. 253 | /// 254 | /// Note that this iterator returns also removed elements, which can be 255 | /// tested with the [`is_removed()`] method on the node. 256 | /// 257 | /// # Examples 258 | /// 259 | /// ``` 260 | /// # use indextree::Arena; 261 | /// let mut arena = Arena::new(); 262 | /// let _foo = arena.new_node("foo"); 263 | /// let _bar = arena.new_node("bar"); 264 | /// 265 | /// let mut iter = arena.iter(); 266 | /// assert_eq!(iter.next().map(|node| *node.get()), Some("foo")); 267 | /// assert_eq!(iter.next().map(|node| *node.get()), Some("bar")); 268 | /// assert_eq!(iter.next().map(|node| *node.get()), None); 269 | /// ``` 270 | /// 271 | /// ``` 272 | /// # use indextree::Arena; 273 | /// let mut arena = Arena::new(); 274 | /// let _foo = arena.new_node("foo"); 275 | /// let bar = arena.new_node("bar"); 276 | /// bar.remove(&mut arena); 277 | /// 278 | /// let mut iter = arena.iter(); 279 | /// assert_eq!(iter.next().map(|node| (*node.get(), node.is_removed())), Some(("foo", false))); 280 | /// assert_eq!(iter.next().map_or(false, |node| node.is_removed()), true); 281 | /// assert_eq!(iter.next().map(|node| (*node.get(), node.is_removed())), None); 282 | /// ``` 283 | /// 284 | /// [`is_removed()`]: struct.Node.html#method.is_removed 285 | pub fn iter(&self) -> slice::Iter> { 286 | self.nodes.iter() 287 | } 288 | 289 | /// Returns a mutable iterator of all nodes in the arena in storage-order. 290 | /// 291 | /// Note that this iterator returns also removed elements, which can be 292 | /// tested with the [`is_removed()`] method on the node. 293 | /// 294 | /// # Example 295 | /// 296 | /// ``` 297 | /// # use indextree::Arena; 298 | /// let arena: &mut Arena = &mut Arena::new(); 299 | /// let a = arena.new_node(1); 300 | /// let b = arena.new_node(2); 301 | /// assert!(a.checked_append(b, arena).is_ok()); 302 | /// 303 | /// for node in arena.iter_mut() { 304 | /// let data = node.get_mut(); 305 | /// *data = data.wrapping_add(4); 306 | /// } 307 | /// 308 | /// let node_refs = arena.iter().map(|i| i.get().clone()).collect::>(); 309 | /// assert_eq!(node_refs, vec![5, 6]); 310 | /// ``` 311 | /// [`is_removed()`]: struct.Node.html#method.is_removed 312 | pub fn iter_mut(&mut self) -> slice::IterMut> { 313 | self.nodes.iter_mut() 314 | } 315 | 316 | /// Clears all the nodes in the arena, but retains its allocated capacity. 317 | /// 318 | /// Note that this does not marks all nodes as removed, but completely 319 | /// removes them from the arena storage, thus invalidating all the node ids 320 | /// that were previously created. 321 | /// 322 | /// Any attempt to call the [`is_removed()`] method on the node id will 323 | /// result in panic behavior. 324 | /// 325 | /// [`is_removed()`]: struct.NodeId.html#method.is_removed 326 | pub fn clear(&mut self) { 327 | self.nodes.clear(); 328 | self.first_free_slot = None; 329 | self.last_free_slot = None; 330 | } 331 | 332 | /// Returns a slice of the inner nodes collection. 333 | /// 334 | /// Note that this **does not** return root elements, it simply 335 | /// returns a slice into the internal representation of the arena. 336 | pub fn as_slice(&self) -> &[Node] { 337 | self.nodes.as_slice() 338 | } 339 | 340 | pub(crate) fn free_node(&mut self, id: NodeId) { 341 | let node = &mut self[id]; 342 | node.data = NodeData::NextFree(None); 343 | node.stamp.as_removed(); 344 | let stamp = node.stamp; 345 | if stamp.reuseable() { 346 | if let Some(index) = self.last_free_slot { 347 | let new_last = id.index0(); 348 | self.nodes[index].data = NodeData::NextFree(Some(new_last)); 349 | self.last_free_slot = Some(new_last); 350 | } else { 351 | debug_assert!(self.first_free_slot.is_none()); 352 | debug_assert!(self.last_free_slot.is_none()); 353 | self.first_free_slot = Some(id.index0()); 354 | self.last_free_slot = Some(id.index0()); 355 | } 356 | } 357 | } 358 | 359 | fn pop_front_free_node(&mut self) -> Option { 360 | let first = self.first_free_slot.take(); 361 | if let Some(index) = first { 362 | if let NodeData::NextFree(next_free) = self.nodes[index].data { 363 | self.first_free_slot = next_free; 364 | } else { 365 | unreachable!("A data node consider as a freed node"); 366 | } 367 | if self.first_free_slot.is_none() { 368 | self.last_free_slot = None; 369 | } 370 | } 371 | 372 | first 373 | } 374 | } 375 | 376 | #[cfg(feature = "par_iter")] 377 | impl Arena { 378 | /// Returns an parallel iterator over the whole arena. 379 | /// 380 | /// Note that this iterator returns also removed elements, which can be 381 | /// tested with the [`is_removed()`] method on the node. 382 | /// 383 | /// [`is_removed()`]: struct.Node.html#method.is_removed 384 | pub fn par_iter(&self) -> rayon::slice::Iter<'_, Node> { 385 | self.nodes.par_iter() 386 | } 387 | } 388 | 389 | impl Default for Arena { 390 | fn default() -> Self { 391 | Self { 392 | nodes: Vec::new(), 393 | first_free_slot: None, 394 | last_free_slot: None, 395 | } 396 | } 397 | } 398 | 399 | impl Index for Arena { 400 | type Output = Node; 401 | 402 | fn index(&self, node: NodeId) -> &Node { 403 | &self.nodes[node.index0()] 404 | } 405 | } 406 | 407 | impl IndexMut for Arena { 408 | fn index_mut(&mut self, node: NodeId) -> &mut Node { 409 | &mut self.nodes[node.index0()] 410 | } 411 | } 412 | 413 | #[test] 414 | fn reuse_node() { 415 | let mut arena = Arena::new(); 416 | let n1_id = arena.new_node("1"); 417 | let n2_id = arena.new_node("2"); 418 | let n3_id = arena.new_node("3"); 419 | n1_id.remove(&mut arena); 420 | n2_id.remove(&mut arena); 421 | n3_id.remove(&mut arena); 422 | let n1_id = arena.new_node("1"); 423 | let n2_id = arena.new_node("2"); 424 | let n3_id = arena.new_node("3"); 425 | assert_eq!(n1_id.index0(), 0); 426 | assert_eq!(n2_id.index0(), 1); 427 | assert_eq!(n3_id.index0(), 2); 428 | assert_eq!(arena.nodes.len(), 3); 429 | } 430 | 431 | #[test] 432 | fn conserve_capacity() { 433 | let mut arena = Arena::with_capacity(5); 434 | let cap = arena.capacity(); 435 | assert!(cap >= 5); 436 | for i in 0..cap { 437 | arena.new_node(i); 438 | } 439 | arena.clear(); 440 | assert!(arena.is_empty()); 441 | let n1_id = arena.new_node(1); 442 | let n2_id = arena.new_node(2); 443 | let n3_id = arena.new_node(3); 444 | assert_eq!(n1_id.index0(), 0); 445 | assert_eq!(n2_id.index0(), 1); 446 | assert_eq!(n3_id.index0(), 2); 447 | assert_eq!(arena.count(), 3); 448 | assert_eq!(arena.capacity(), cap); 449 | } 450 | -------------------------------------------------------------------------------- /indextree/src/debug_pretty_print.rs: -------------------------------------------------------------------------------- 1 | //! Debug printer. 2 | 3 | use core::fmt::{self, Write as _}; 4 | 5 | #[cfg(not(feature = "std"))] 6 | use alloc::vec::Vec; 7 | #[cfg(feature = "std")] 8 | use std::vec::Vec; 9 | 10 | use crate::{ 11 | arena::Arena, 12 | id::NodeId, 13 | traverse::{NodeEdge, Traverse}, 14 | }; 15 | 16 | //use crate::dynamic::hierarchy::traverse::{DepthFirstTraverser, DftEvent}; 17 | //use crate::dynamic::hierarchy::Hierarchy; 18 | 19 | /// State of an indent block. 20 | #[derive(Clone, Copy)] 21 | struct IndentedBlockState { 22 | /// Whether this is the last item. 23 | is_last_item: bool, 24 | /// Whether the line is the first line. 25 | is_first_line: bool, 26 | } 27 | 28 | impl IndentedBlockState { 29 | /// Returns the indent string for the indent type. 30 | #[inline] 31 | fn as_str(self) -> &'static str { 32 | match (self.is_last_item, self.is_first_line) { 33 | (false, true) => "|-- ", 34 | (false, false) => "| ", 35 | (true, true) => "`-- ", 36 | (true, false) => " ", 37 | } 38 | } 39 | 40 | /// Returns the leading part of the indent string. 41 | #[inline] 42 | fn as_str_leading(self) -> &'static str { 43 | match (self.is_last_item, self.is_first_line) { 44 | (false, true) => "|--", 45 | (false, false) => "|", 46 | (true, true) => "`--", 47 | (true, false) => "", 48 | } 49 | } 50 | 51 | /// Returns the trailing whitespaces part of the indent string. 52 | #[inline] 53 | fn as_str_trailing_spaces(self) -> &'static str { 54 | match (self.is_last_item, self.is_first_line) { 55 | (_, true) => " ", 56 | (false, false) => " ", 57 | (true, false) => " ", 58 | } 59 | } 60 | 61 | /// Returns whether the indent string consists of only whitespaces. 62 | #[inline] 63 | #[must_use] 64 | fn is_all_whitespace(self) -> bool { 65 | self.is_last_item && !self.is_first_line 66 | } 67 | } 68 | 69 | /// State of the line writing. 70 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 71 | enum LineState { 72 | /// Before any character of the indent is written to the current line. 73 | BeforeIndent, 74 | /// Indents are partially written. 75 | /// 76 | /// More precisely, trailing whitespaces are not yet written. 77 | PartialIndent, 78 | /// Writing content. 79 | Content, 80 | } 81 | 82 | /// Indent writer for the debug printer. 83 | struct IndentWriter<'a, 'b> { 84 | /// Backend formatter. 85 | fmt: &'b mut fmt::Formatter<'a>, 86 | /// State of the line writing. 87 | line_state: LineState, 88 | /// Indents. 89 | indents: Vec, 90 | /// The number of pending whitespace-only indents. 91 | pending_ws_only_indent_level: usize, 92 | } 93 | 94 | impl<'a, 'b> IndentWriter<'a, 'b> { 95 | /// Creates a new `PadAdapter`. 96 | #[inline] 97 | fn new(fmt: &'b mut fmt::Formatter<'a>) -> Self { 98 | Self { 99 | fmt, 100 | line_state: LineState::BeforeIndent, 101 | indents: Vec::new(), 102 | pending_ws_only_indent_level: 0, 103 | } 104 | } 105 | 106 | /// Opens the next item. 107 | /// 108 | /// Writes a newline if necessary and prepares to write the next item. 109 | /// 110 | /// This should **not** be called for the root item. 111 | fn open_item(&mut self, is_last_item: bool) -> fmt::Result { 112 | if self.line_state != LineState::BeforeIndent { 113 | self.fmt.write_char('\n')?; 114 | self.line_state = LineState::BeforeIndent; 115 | self.pending_ws_only_indent_level = 0; 116 | } 117 | if let Some(indent) = self.indents.last_mut() { 118 | indent.is_first_line = false; 119 | } 120 | self.indents.push(IndentedBlockState { 121 | is_last_item, 122 | is_first_line: true, 123 | }); 124 | 125 | Ok(()) 126 | } 127 | 128 | /// Closes the current item. 129 | /// 130 | /// Returns `Ok(())` if an item is successfully closed. 131 | /// Returns `Err(())` if there are no items that can be closed, i.e. the 132 | /// current item is the root. 133 | #[inline] 134 | fn close_item(&mut self) -> Result<(), ()> { 135 | match self.indents.pop() { 136 | Some(_) => Ok(()), 137 | None => Err(()), 138 | } 139 | } 140 | 141 | /// Writes the indent except for the trailing whitespaces. 142 | fn write_indent_partial(&mut self) -> fmt::Result { 143 | self.pending_ws_only_indent_level = self 144 | .indents 145 | .iter() 146 | .rev() 147 | .take_while(|i| i.is_all_whitespace()) 148 | .count(); 149 | 150 | let ws_indent_first_level = self.indents.len() - self.pending_ws_only_indent_level; 151 | let indents_to_print = &self.indents[..ws_indent_first_level]; 152 | if let Some(last) = indents_to_print.last() { 153 | for indent in &indents_to_print[..(indents_to_print.len() - 1)] { 154 | self.fmt.write_str(indent.as_str())?; 155 | } 156 | self.fmt.write_str(last.as_str_leading())?; 157 | } 158 | 159 | Ok(()) 160 | } 161 | 162 | /// Writes the rest of the indents which are partially written. 163 | fn complete_partial_indent(&mut self) -> fmt::Result { 164 | debug_assert_eq!(self.line_state, LineState::PartialIndent); 165 | if let Some(last_non_ws_indent_level) = 166 | (self.indents.len() - self.pending_ws_only_indent_level).checked_sub(1) 167 | { 168 | self.fmt 169 | .write_str(self.indents[last_non_ws_indent_level].as_str_trailing_spaces())?; 170 | } 171 | for _ in 0..self.pending_ws_only_indent_level { 172 | self.fmt.write_str(" ")?; 173 | } 174 | self.pending_ws_only_indent_level = 0; 175 | 176 | Ok(()) 177 | } 178 | } 179 | 180 | impl fmt::Write for IndentWriter<'_, '_> { 181 | fn write_str(&mut self, mut s: &str) -> fmt::Result { 182 | while !s.is_empty() { 183 | // There remains something to print. 184 | 185 | if self.line_state == LineState::BeforeIndent { 186 | self.write_indent_partial()?; 187 | self.line_state = LineState::PartialIndent; 188 | } 189 | 190 | let (line_end, ends_with_newline) = match s.find('\n') { 191 | Some(pos) => (pos + 1, true), 192 | None => (s.len(), false), 193 | }; 194 | let content = &s[..line_end]; 195 | if !content.is_empty() { 196 | debug_assert_ne!( 197 | self.line_state, 198 | LineState::BeforeIndent, 199 | "[consistency] indent must be written since there are something to write" 200 | ); 201 | if self.line_state == LineState::PartialIndent { 202 | self.complete_partial_indent()?; 203 | } 204 | if let Some(level) = self.indents.last_mut() { 205 | level.is_first_line = level.is_first_line && !ends_with_newline; 206 | } 207 | self.fmt.write_str(content)?; 208 | 209 | self.line_state = if ends_with_newline { 210 | LineState::BeforeIndent 211 | } else { 212 | LineState::Content 213 | }; 214 | } 215 | s = &s[line_end..]; 216 | } 217 | 218 | Ok(()) 219 | } 220 | } 221 | 222 | /// Tree printer for debugging. 223 | /// 224 | /// This is provided mainly for debugging purpose. Node that the output format 225 | /// is not guaranteed to be stable, and any format changes won't be considered 226 | /// as breaking changes. 227 | /// 228 | /// For usage and output examples, see 229 | /// [`NodeId::debug_pretty_print`][`crate::NodeId::debug_pretty_print`] method. 230 | #[derive(Clone, Copy)] 231 | pub struct DebugPrettyPrint<'a, T> { 232 | /// Root node ID of the (sub)tree to print. 233 | id: &'a NodeId, 234 | /// Arena the node belongs to. 235 | arena: &'a Arena, 236 | } 237 | 238 | impl<'a, T> DebugPrettyPrint<'a, T> { 239 | /// Creates a new `DebugPrettyPrint` object for the node. 240 | #[inline] 241 | pub(crate) fn new(id: &'a NodeId, arena: &'a Arena) -> Self { 242 | Self { id, arena } 243 | } 244 | } 245 | 246 | impl fmt::Display for DebugPrettyPrint<'_, T> { 247 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 248 | let is_alternate = f.alternate(); 249 | let mut writer = IndentWriter::new(f); 250 | let mut traverser = self.id.traverse(self.arena); 251 | 252 | // Print the first (root) node. 253 | traverser.next(); 254 | { 255 | let data = self.arena[*self.id].get(); 256 | if is_alternate { 257 | write!(writer, "{:#}", data)? 258 | } else { 259 | write!(writer, "{}", data)? 260 | } 261 | } 262 | 263 | // Print the descendants. 264 | while let Some(id) = prepare_next_node_printing(&mut writer, &mut traverser)? { 265 | let data = traverser.arena()[id].get(); 266 | if is_alternate { 267 | write!(writer, "{:#}", data)? 268 | } else { 269 | write!(writer, "{}", data)? 270 | } 271 | } 272 | 273 | Ok(()) 274 | } 275 | } 276 | 277 | impl fmt::Debug for DebugPrettyPrint<'_, T> { 278 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 279 | let is_alternate = f.alternate(); 280 | let mut writer = IndentWriter::new(f); 281 | let mut traverser = self.id.traverse(self.arena); 282 | 283 | // Print the first (root) node. 284 | traverser.next(); 285 | { 286 | let data = self.arena[*self.id].get(); 287 | if is_alternate { 288 | write!(writer, "{:#?}", data)? 289 | } else { 290 | write!(writer, "{:?}", data)? 291 | } 292 | } 293 | 294 | // Print the descendants. 295 | while let Some(id) = prepare_next_node_printing(&mut writer, &mut traverser)? { 296 | let data = traverser.arena()[id].get(); 297 | if is_alternate { 298 | write!(writer, "{:#?}", data)? 299 | } else { 300 | write!(writer, "{:?}", data)? 301 | } 302 | } 303 | 304 | Ok(()) 305 | } 306 | } 307 | 308 | /// Prepares printing of next node. 309 | /// 310 | /// Internally, this searches next node open and adjust indent level and prefix. 311 | fn prepare_next_node_printing( 312 | writer: &mut IndentWriter<'_, '_>, 313 | traverser: &mut Traverse<'_, T>, 314 | ) -> Result, fmt::Error> { 315 | // Not using `for ev in traverser` in order to access to `traverser` 316 | // directly in the loop. 317 | while let Some(ev) = traverser.next() { 318 | let id = match ev { 319 | NodeEdge::Start(id) => id, 320 | NodeEdge::End(_) => { 321 | if writer.close_item().is_ok() { 322 | // Closed a non-root node. 323 | continue; 324 | } else { 325 | // Closed the root node. 326 | break; 327 | } 328 | } 329 | }; 330 | let is_last_sibling = traverser.arena()[id].next_sibling().is_none(); 331 | writer.open_item(is_last_sibling)?; 332 | 333 | return Ok(Some(id)); 334 | } 335 | 336 | Ok(None) 337 | } 338 | -------------------------------------------------------------------------------- /indextree/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Errors. 2 | 3 | #[cfg(not(feature = "std"))] 4 | use core::fmt; 5 | 6 | #[cfg(feature = "std")] 7 | use std::{error, fmt}; 8 | 9 | #[non_exhaustive] 10 | #[derive(Debug, Clone, Copy)] 11 | /// Possible node failures. 12 | pub enum NodeError { 13 | /// Attempt to append a node to itself. 14 | AppendSelf, 15 | /// Attempt to prepend a node to itself. 16 | PrependSelf, 17 | /// Attempt to insert a node before itself. 18 | InsertBeforeSelf, 19 | /// Attempt to insert a node after itself. 20 | InsertAfterSelf, 21 | /// Attempt to insert a removed node, or insert to a removed node. 22 | Removed, 23 | /// Attempt to append an ancestor node to a descendant. 24 | AppendAncestor, 25 | /// Attempt to prepend an ancestor node to a descendant. 26 | PrependAncestor, 27 | } 28 | 29 | impl NodeError { 30 | fn as_str(self) -> &'static str { 31 | match self { 32 | NodeError::AppendSelf => "Can not append a node to itself", 33 | NodeError::PrependSelf => "Can not prepend a node to itself", 34 | NodeError::InsertBeforeSelf => "Can not insert a node before itself", 35 | NodeError::InsertAfterSelf => "Can not insert a node after itself", 36 | NodeError::Removed => "Removed node cannot have any parent, siblings, and children", 37 | NodeError::AppendAncestor => "Can not append a node to its descendant", 38 | NodeError::PrependAncestor => "Can not prepend a node to its descendant", 39 | } 40 | } 41 | } 42 | 43 | impl fmt::Display for NodeError { 44 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 45 | f.write_str(self.as_str()) 46 | } 47 | } 48 | 49 | #[cfg(feature = "std")] 50 | impl error::Error for NodeError {} 51 | 52 | /// An error type that represents the given structure or argument is 53 | /// inconsistent or invalid. 54 | // Intended for internal use. 55 | #[derive(Debug, Clone, Copy)] 56 | pub(crate) enum ConsistencyError { 57 | /// Specified a node as its parent. 58 | ParentChildLoop, 59 | /// Specified a node as its sibling. 60 | SiblingsLoop, 61 | } 62 | 63 | impl fmt::Display for ConsistencyError { 64 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 65 | match self { 66 | ConsistencyError::ParentChildLoop => f.write_str("Specified a node as its parent"), 67 | ConsistencyError::SiblingsLoop => f.write_str("Specified a node as its sibling"), 68 | } 69 | } 70 | } 71 | 72 | #[cfg(feature = "std")] 73 | impl error::Error for ConsistencyError {} 74 | -------------------------------------------------------------------------------- /indextree/src/id.rs: -------------------------------------------------------------------------------- 1 | //! Node ID. 2 | 3 | #[cfg(not(feature = "std"))] 4 | use core::{fmt, num::NonZeroUsize}; 5 | 6 | #[cfg(feature = "deser")] 7 | use serde::{Deserialize, Serialize}; 8 | 9 | #[cfg(feature = "std")] 10 | use std::{fmt, num::NonZeroUsize}; 11 | 12 | #[allow(deprecated)] 13 | use crate::{ 14 | debug_pretty_print::DebugPrettyPrint, 15 | relations::{insert_last_unchecked, insert_with_neighbors}, 16 | siblings_range::SiblingsRange, 17 | Ancestors, Arena, Children, Descendants, FollowingSiblings, NodeError, PrecedingSiblings, 18 | Predecessors, ReverseChildren, ReverseTraverse, Traverse, 19 | }; 20 | 21 | #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug, Hash)] 22 | #[cfg_attr(feature = "deser", derive(Deserialize, Serialize))] 23 | /// A node identifier within a particular [`Arena`]. 24 | /// 25 | /// This ID is used to get [`Node`] references from an [`Arena`]. 26 | /// 27 | /// [`Arena`]: struct.Arena.html 28 | /// [`Node`]: struct.Node.html 29 | pub struct NodeId { 30 | /// One-based index. 31 | index1: NonZeroUsize, 32 | stamp: NodeStamp, 33 | } 34 | 35 | /// A stamp for node reuse, use to detect if the node of a `NodeId` point to 36 | /// is still the same node. 37 | #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug, Hash, Default)] 38 | #[cfg_attr(feature = "deser", derive(Deserialize, Serialize))] 39 | pub(crate) struct NodeStamp(i16); 40 | 41 | impl NodeStamp { 42 | pub fn is_removed(self) -> bool { 43 | self.0.is_negative() 44 | } 45 | 46 | pub fn as_removed(&mut self) { 47 | debug_assert!(!self.is_removed()); 48 | self.0 = if self.0 < i16::MAX { 49 | -self.0 - 1 50 | } else { 51 | -self.0 52 | }; 53 | } 54 | 55 | pub fn reuseable(self) -> bool { 56 | debug_assert!(self.is_removed()); 57 | self.0 > i16::MIN 58 | } 59 | 60 | pub fn reuse(&mut self) -> Self { 61 | debug_assert!(self.reuseable()); 62 | self.0 = -self.0; 63 | *self 64 | } 65 | } 66 | 67 | impl fmt::Display for NodeId { 68 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 69 | write!(f, "{}", self.index1) 70 | } 71 | } 72 | 73 | impl From for NonZeroUsize { 74 | fn from(value: NodeId) -> NonZeroUsize { 75 | value.index1 76 | } 77 | } 78 | 79 | impl From for usize { 80 | fn from(value: NodeId) -> usize { 81 | value.index1.get() 82 | } 83 | } 84 | 85 | impl NodeId { 86 | /// Returns zero-based index. 87 | pub(crate) fn index0(self) -> usize { 88 | // This is totally safe because `self.index1 >= 1` is guaranteed by 89 | // `NonZeroUsize` type. 90 | self.index1.get() - 1 91 | } 92 | 93 | /// Creates a new `NodeId` from the given one-based index. 94 | pub(crate) fn from_non_zero_usize(index1: NonZeroUsize, stamp: NodeStamp) -> Self { 95 | NodeId { index1, stamp } 96 | } 97 | 98 | /// Return if the `Node` of NodeId point to is removed. 99 | pub fn is_removed(self, arena: &Arena) -> bool { 100 | arena[self].stamp != self.stamp 101 | } 102 | 103 | /// Returns an iterator of IDs of this node and its ancestors. 104 | /// 105 | /// Use [`.skip(1)`][`skip`] or call `.next()` once on the iterator to skip 106 | /// the node itself. 107 | /// 108 | /// # Examples 109 | /// 110 | /// ``` 111 | /// # use indextree::Arena; 112 | /// # let mut arena = Arena::new(); 113 | /// # let n1 = arena.new_node("1"); 114 | /// # let n1_1 = arena.new_node("1_1"); 115 | /// # n1.append(n1_1, &mut arena); 116 | /// # let n1_1_1 = arena.new_node("1_1_1"); 117 | /// # n1_1.append(n1_1_1, &mut arena); 118 | /// # let n1_1_1_1 = arena.new_node("1_1_1_1"); 119 | /// # n1_1_1.append(n1_1_1_1, &mut arena); 120 | /// # let n1_2 = arena.new_node("1_2"); 121 | /// # n1.append(n1_2, &mut arena); 122 | /// # let n1_3 = arena.new_node("1_3"); 123 | /// # n1.append(n1_3, &mut arena); 124 | /// # 125 | /// // arena 126 | /// // `-- 1 // #3 127 | /// // |-- 1_1 // #2 128 | /// // | `-- 1_1_1 * // #1 129 | /// // | `-- 1_1_1_1 130 | /// // _-- 1_2 131 | /// // `-- 1_3 132 | /// 133 | /// let mut iter = n1_1_1.ancestors(&arena); 134 | /// assert_eq!(iter.next(), Some(n1_1_1)); // #1 135 | /// assert_eq!(iter.next(), Some(n1_1)); // #2 136 | /// assert_eq!(iter.next(), Some(n1)); // #3 137 | /// assert_eq!(iter.next(), None); 138 | /// ``` 139 | /// 140 | /// [`skip`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.skip 141 | pub fn ancestors(self, arena: &Arena) -> Ancestors<'_, T> { 142 | Ancestors::new(arena, self) 143 | } 144 | 145 | /// Returns an iterator of IDs of this node and its predecessors. 146 | /// 147 | /// Use [`.skip(1)`][`skip`] or call `.next()` once on the iterator to skip 148 | /// the node itself. 149 | /// 150 | /// # Examples 151 | /// 152 | /// ``` 153 | /// # use indextree::Arena; 154 | /// # let mut arena = Arena::new(); 155 | /// # let n1 = arena.new_node("1"); 156 | /// # let n1_1 = arena.new_node("1_1"); 157 | /// # n1.append(n1_1, &mut arena); 158 | /// # let n1_1_1 = arena.new_node("1_1_1"); 159 | /// # n1_1.append(n1_1_1, &mut arena); 160 | /// # let n1_1_1_1 = arena.new_node("1_1_1_1"); 161 | /// # n1_1_1.append(n1_1_1_1, &mut arena); 162 | /// # let n1_2 = arena.new_node("1_2"); 163 | /// # n1.append(n1_2, &mut arena); 164 | /// # let n1_3 = arena.new_node("1_3"); 165 | /// # n1.append(n1_3, &mut arena); 166 | /// # 167 | /// // arena 168 | /// // `-- 1 // #3 169 | /// // |-- 1_1 // #2 170 | /// // | `-- 1_1_1 * // #1 171 | /// // | `-- 1_1_1_1 172 | /// // _-- 1_2 173 | /// // `-- 1_3 174 | /// 175 | /// let mut iter = n1_1_1.predecessors(&arena); 176 | /// assert_eq!(iter.next(), Some(n1_1_1)); // #1 177 | /// assert_eq!(iter.next(), Some(n1_1)); // #2 178 | /// assert_eq!(iter.next(), Some(n1)); // #3 179 | /// assert_eq!(iter.next(), None); 180 | /// ``` 181 | /// 182 | /// ``` 183 | /// # use indextree::Arena; 184 | /// # let mut arena = Arena::new(); 185 | /// # let n1 = arena.new_node("1"); 186 | /// # let n1_1 = arena.new_node("1_1"); 187 | /// # n1.append(n1_1, &mut arena); 188 | /// # let n1_2 = arena.new_node("1_2"); 189 | /// # n1.append(n1_2, &mut arena); 190 | /// # let n1_2_1 = arena.new_node("1_2_1"); 191 | /// # n1_2.append(n1_2_1, &mut arena); 192 | /// # let n1_2_1_1 = arena.new_node("1_2_1_1"); 193 | /// # n1_2_1.append(n1_2_1_1, &mut arena); 194 | /// # let n1_3 = arena.new_node("1_3"); 195 | /// # n1.append(n1_3, &mut arena); 196 | /// # let n1_4 = arena.new_node("1_4"); 197 | /// # n1.append(n1_4, &mut arena); 198 | /// # 199 | /// // arena 200 | /// // `-- 1 // #4 201 | /// // |-- 1_1 // #3 202 | /// // |-- 1_2 // #2 203 | /// // | `-- 1_2_1 * // #1 204 | /// // | `-- 1_2_1_1 205 | /// // _-- 1_3 206 | /// // `-- 1_4 207 | /// 208 | /// let mut iter = n1_2_1.predecessors(&arena); 209 | /// assert_eq!(iter.next(), Some(n1_2_1)); // #1 210 | /// assert_eq!(iter.next(), Some(n1_2)); // #2 211 | /// assert_eq!(iter.next(), Some(n1_1)); // #3 212 | /// assert_eq!(iter.next(), Some(n1)); // #4 213 | /// assert_eq!(iter.next(), None); 214 | /// ``` 215 | /// 216 | /// [`skip`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.skip 217 | pub fn predecessors(self, arena: &Arena) -> Predecessors<'_, T> { 218 | Predecessors::new(arena, self) 219 | } 220 | 221 | /// Returns an iterator of IDs of this node and the siblings before it. 222 | /// 223 | /// Use [`.skip(1)`][`skip`] or call `.next()` once on the iterator to skip 224 | /// the node itself. 225 | /// 226 | /// # Examples 227 | /// 228 | /// ``` 229 | /// # use indextree::Arena; 230 | /// # let mut arena = Arena::new(); 231 | /// # let n1 = arena.new_node("1"); 232 | /// # let n1_1 = arena.new_node("1_1"); 233 | /// # n1.append(n1_1, &mut arena); 234 | /// # let n1_1_1 = arena.new_node("1_1_1"); 235 | /// # n1_1.append(n1_1_1, &mut arena); 236 | /// # let n1_2 = arena.new_node("1_2"); 237 | /// # n1.append(n1_2, &mut arena); 238 | /// # let n1_3 = arena.new_node("1_3"); 239 | /// # n1.append(n1_3, &mut arena); 240 | /// # 241 | /// // arena 242 | /// // `-- 1 243 | /// // |-- 1_1 // #2 244 | /// // | `-- 1_1_1 245 | /// // |-- 1_2 // #1 246 | /// // `-- 1_3 247 | /// 248 | /// let mut iter = n1_2.preceding_siblings(&arena); 249 | /// assert_eq!(iter.next(), Some(n1_2)); // #1 250 | /// assert_eq!(iter.next(), Some(n1_1)); // #2 251 | /// assert_eq!(iter.next(), None); 252 | /// ``` 253 | /// 254 | /// [`skip`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.skip 255 | pub fn preceding_siblings(self, arena: &Arena) -> PrecedingSiblings<'_, T> { 256 | PrecedingSiblings::new(arena, self) 257 | } 258 | 259 | /// Returns an iterator of IDs of this node and the siblings after 260 | /// it. 261 | /// 262 | /// Use [`.skip(1)`][`skip`] or call `.next()` once on the iterator to skip 263 | /// the node itself. 264 | /// 265 | /// # Examples 266 | /// 267 | /// ``` 268 | /// # use indextree::Arena; 269 | /// # let mut arena = Arena::new(); 270 | /// # let n1 = arena.new_node("1"); 271 | /// # let n1_1 = arena.new_node("1_1"); 272 | /// # n1.append(n1_1, &mut arena); 273 | /// # let n1_1_1 = arena.new_node("1_1_1"); 274 | /// # n1_1.append(n1_1_1, &mut arena); 275 | /// # let n1_2 = arena.new_node("1_2"); 276 | /// # n1.append(n1_2, &mut arena); 277 | /// # let n1_3 = arena.new_node("1_3"); 278 | /// # n1.append(n1_3, &mut arena); 279 | /// # 280 | /// // arena 281 | /// // `-- 1 282 | /// // |-- 1_1 283 | /// // | `-- 1_1_1 284 | /// // |-- 1_2 // #1 285 | /// // `-- 1_3 // #2 286 | /// 287 | /// let mut iter = n1_2.following_siblings(&arena); 288 | /// assert_eq!(iter.next(), Some(n1_2)); // #1 289 | /// assert_eq!(iter.next(), Some(n1_3)); // #2 290 | /// assert_eq!(iter.next(), None); 291 | /// ``` 292 | /// 293 | /// [`skip`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.skip 294 | pub fn following_siblings(self, arena: &Arena) -> FollowingSiblings<'_, T> { 295 | FollowingSiblings::new(arena, self) 296 | } 297 | 298 | /// Returns an iterator of IDs of this node’s children. 299 | /// 300 | /// # Examples 301 | /// 302 | /// ``` 303 | /// # use indextree::Arena; 304 | /// # let mut arena = Arena::new(); 305 | /// # let n1 = arena.new_node("1"); 306 | /// # let n1_1 = arena.new_node("1_1"); 307 | /// # n1.append(n1_1, &mut arena); 308 | /// # let n1_1_1 = arena.new_node("1_1_1"); 309 | /// # n1_1.append(n1_1_1, &mut arena); 310 | /// # let n1_2 = arena.new_node("1_2"); 311 | /// # n1.append(n1_2, &mut arena); 312 | /// # let n1_3 = arena.new_node("1_3"); 313 | /// # n1.append(n1_3, &mut arena); 314 | /// # 315 | /// // arena 316 | /// // `-- 1 317 | /// // |-- 1_1 // #1 318 | /// // | `-- 1_1_1 319 | /// // |-- 1_2 // #2 320 | /// // `-- 1_3 // #3 321 | /// 322 | /// let mut iter = n1.children(&arena); 323 | /// assert_eq!(iter.next(), Some(n1_1)); // #1 324 | /// assert_eq!(iter.next(), Some(n1_2)); // #2 325 | /// assert_eq!(iter.next(), Some(n1_3)); // #3 326 | /// assert_eq!(iter.next(), None); 327 | /// ``` 328 | pub fn children(self, arena: &Arena) -> Children<'_, T> { 329 | Children::new(arena, self) 330 | } 331 | 332 | /// Returns an iterator of IDs of this node’s children, in reverse 333 | /// order. 334 | /// 335 | /// # Examples 336 | /// 337 | /// ``` 338 | /// # use indextree::Arena; 339 | /// # let mut arena = Arena::new(); 340 | /// # let n1 = arena.new_node("1"); 341 | /// # let n1_1 = arena.new_node("1_1"); 342 | /// # n1.append(n1_1, &mut arena); 343 | /// # let n1_1_1 = arena.new_node("1_1_1"); 344 | /// # n1_1.append(n1_1_1, &mut arena); 345 | /// # let n1_2 = arena.new_node("1_2"); 346 | /// # n1.append(n1_2, &mut arena); 347 | /// # let n1_3 = arena.new_node("1_3"); 348 | /// # n1.append(n1_3, &mut arena); 349 | /// # 350 | /// // arena 351 | /// // `-- 1 352 | /// // |-- 1_1 // #3 353 | /// // | `-- 1_1_1 354 | /// // |-- 1_2 // #2 355 | /// // `-- 1_3 // #1 356 | /// 357 | /// let mut iter = n1.reverse_children(&arena); 358 | /// assert_eq!(iter.next(), Some(n1_3)); // #1 359 | /// assert_eq!(iter.next(), Some(n1_2)); // #2 360 | /// assert_eq!(iter.next(), Some(n1_1)); // #3 361 | /// assert_eq!(iter.next(), None); 362 | /// ``` 363 | #[allow(deprecated)] 364 | #[deprecated( 365 | since = "4.7.0", 366 | note = "please, use `NodeId::children().rev()` instead if you want to iterate in reverse" 367 | )] 368 | pub fn reverse_children(self, arena: &Arena) -> ReverseChildren<'_, T> { 369 | ReverseChildren::new(arena, self) 370 | } 371 | 372 | /// An iterator of the IDs of a given node and its descendants, as a pre-order depth-first search where children are visited in insertion order. 373 | /// 374 | /// i.e. node -> first child -> second child 375 | /// 376 | /// Parent nodes appear before the descendants. 377 | /// Use [`.skip(1)`][`skip`] or call `.next()` once on the iterator to skip 378 | /// the node itself. 379 | /// 380 | /// # Examples 381 | /// 382 | /// ``` 383 | /// # use indextree::Arena; 384 | /// # let mut arena = Arena::new(); 385 | /// # let n1 = arena.new_node("1"); 386 | /// # let n1_1 = arena.new_node("1_1"); 387 | /// # n1.append(n1_1, &mut arena); 388 | /// # let n1_1_1 = arena.new_node("1_1_1"); 389 | /// # n1_1.append(n1_1_1, &mut arena); 390 | /// # let n1_1_1_1 = arena.new_node("1_1_1_1"); 391 | /// # n1_1_1.append(n1_1_1_1, &mut arena); 392 | /// # let n1_2 = arena.new_node("1_2"); 393 | /// # n1.append(n1_2, &mut arena); 394 | /// # let n1_3 = arena.new_node("1_3"); 395 | /// # n1.append(n1_3, &mut arena); 396 | /// # 397 | /// // arena 398 | /// // `-- 1 // #1 399 | /// // |-- 1_1 // #2 400 | /// // | `-- 1_1_1 // #3 401 | /// // | `-- 1_1_1_1 // #4 402 | /// // |-- 1_2 // #5 403 | /// // `-- 1_3 // #6 404 | /// 405 | /// let mut iter = n1.descendants(&arena); 406 | /// assert_eq!(iter.next(), Some(n1)); // #1 407 | /// assert_eq!(iter.next(), Some(n1_1)); // #2 408 | /// assert_eq!(iter.next(), Some(n1_1_1)); // #3 409 | /// assert_eq!(iter.next(), Some(n1_1_1_1)); // #4 410 | /// assert_eq!(iter.next(), Some(n1_2)); // #5 411 | /// assert_eq!(iter.next(), Some(n1_3)); // #6 412 | /// assert_eq!(iter.next(), None); 413 | /// ``` 414 | /// 415 | /// [`skip`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.skip 416 | pub fn descendants(self, arena: &Arena) -> Descendants<'_, T> { 417 | Descendants::new(arena, self) 418 | } 419 | 420 | /// An iterator of the "sides" of a node visited during a depth-first pre-order traversal, 421 | /// where node sides are visited start to end and children are visited in insertion order. 422 | /// 423 | /// i.e. node.start -> first child -> second child -> node.end 424 | /// 425 | /// # Examples 426 | /// 427 | /// ``` 428 | /// # use indextree::{Arena, NodeEdge}; 429 | /// # let mut arena = Arena::new(); 430 | /// # let n1 = arena.new_node("1"); 431 | /// # let n1_1 = arena.new_node("1_1"); 432 | /// # n1.append(n1_1, &mut arena); 433 | /// # let n1_1_1 = arena.new_node("1_1_1"); 434 | /// # n1_1.append(n1_1_1, &mut arena); 435 | /// # let n1_2 = arena.new_node("1_2"); 436 | /// # n1.append(n1_2, &mut arena); 437 | /// # let n1_3 = arena.new_node("1_3"); 438 | /// # n1.append(n1_3, &mut arena); 439 | /// # 440 | /// // arena 441 | /// // `-- 1 // #1, #10 442 | /// // |-- 1_1 // #2, #5 443 | /// // | `-- 1_1_1 // #3, #4 444 | /// // |-- 1_2 // #6, #7 445 | /// // `-- 1_3 // #8, #9 446 | /// 447 | /// let mut iter = n1.traverse(&arena); 448 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1))); // #1 449 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_1))); // #2 450 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_1_1))); // #3 451 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_1_1))); // #4 452 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_1))); // #5 453 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_2))); // #6 454 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_2))); // #7 455 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_3))); // #8 456 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_3))); // #9 457 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1))); // #10 458 | /// assert_eq!(iter.next(), None); 459 | /// ``` 460 | pub fn traverse(self, arena: &Arena) -> Traverse<'_, T> { 461 | Traverse::new(arena, self) 462 | } 463 | 464 | /// An iterator of the "sides" of a node visited during a depth-first pre-order traversal, 465 | /// where nodes are visited end to start and children are visited in reverse insertion order. 466 | /// 467 | /// i.e. node.end -> second child -> first child -> node.start 468 | /// 469 | /// # Examples 470 | /// 471 | /// ``` 472 | /// # use indextree::{Arena, NodeEdge}; 473 | /// # let mut arena = Arena::new(); 474 | /// # let n1 = arena.new_node("1"); 475 | /// # let n1_1 = arena.new_node("1_1"); 476 | /// # n1.append(n1_1, &mut arena); 477 | /// # let n1_1_1 = arena.new_node("1_1_1"); 478 | /// # n1_1.append(n1_1_1, &mut arena); 479 | /// # let n1_2 = arena.new_node("1_2"); 480 | /// # n1.append(n1_2, &mut arena); 481 | /// # let n1_3 = arena.new_node("1_3"); 482 | /// # n1.append(n1_3, &mut arena); 483 | /// # 484 | /// // arena 485 | /// // `-- 1 // #1, #10 486 | /// // |-- 1_1 // #6, #9 487 | /// // | `-- 1_1_1 // #7, #8 488 | /// // |-- 1_2 // #4, #5 489 | /// // `-- 1_3 // #2, #3 490 | /// 491 | /// let mut iter = n1.reverse_traverse(&arena); 492 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1))); // #1 493 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_3))); // #2 494 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_3))); // #3 495 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_2))); // #4 496 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_2))); // #5 497 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_1))); // #6 498 | /// assert_eq!(iter.next(), Some(NodeEdge::End(n1_1_1))); // #7 499 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_1_1))); // #8 500 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1_1))); // #9 501 | /// assert_eq!(iter.next(), Some(NodeEdge::Start(n1))); // #10 502 | /// assert_eq!(iter.next(), None); 503 | /// ``` 504 | /// 505 | /// ``` 506 | /// # use indextree::{Arena, NodeEdge}; 507 | /// # let mut arena = Arena::new(); 508 | /// # let n1 = arena.new_node("1"); 509 | /// # let n1_1 = arena.new_node("1_1"); 510 | /// # n1.append(n1_1, &mut arena); 511 | /// # let n1_1_1 = arena.new_node("1_1_1"); 512 | /// # n1_1.append(n1_1_1, &mut arena); 513 | /// # let n1_2 = arena.new_node("1_2"); 514 | /// # n1.append(n1_2, &mut arena); 515 | /// # let n1_3 = arena.new_node("1_3"); 516 | /// # n1.append(n1_3, &mut arena); 517 | /// # 518 | /// // arena 519 | /// // `-- 1 // #1, #10 520 | /// // |-- 1_1 // #6, #9 521 | /// // | `-- 1_1_1 // #7, #8 522 | /// // |-- 1_2 // #4, #5 523 | /// // `-- 1_3 // #2, #3 524 | /// let traverse = n1.traverse(&arena).collect::>(); 525 | /// let mut reverse = n1.reverse_traverse(&arena).collect::>(); 526 | /// reverse.reverse(); 527 | /// assert_eq!(traverse, reverse); 528 | /// ``` 529 | pub fn reverse_traverse(self, arena: &Arena) -> ReverseTraverse<'_, T> { 530 | ReverseTraverse::new(arena, self) 531 | } 532 | 533 | /// Detaches a node from its parent and siblings. Children are not affected. 534 | /// 535 | /// # Examples 536 | /// 537 | /// ``` 538 | /// # use indextree::{Arena, NodeEdge}; 539 | /// # let mut arena = Arena::new(); 540 | /// # let n1 = arena.new_node("1"); 541 | /// # let n1_1 = arena.new_node("1_1"); 542 | /// # n1.append(n1_1, &mut arena); 543 | /// # let n1_1_1 = arena.new_node("1_1_1"); 544 | /// # n1_1.append(n1_1_1, &mut arena); 545 | /// # let n1_2 = arena.new_node("1_2"); 546 | /// # n1.append(n1_2, &mut arena); 547 | /// # let n1_3 = arena.new_node("1_3"); 548 | /// # n1.append(n1_3, &mut arena); 549 | /// # 550 | /// // arena 551 | /// // `-- (implicit) 552 | /// // `-- 1 553 | /// // |-- 1_1 554 | /// // | `-- 1_1_1 555 | /// // |-- 1_2 * 556 | /// // `-- 1_3 557 | /// 558 | /// n1_2.detach(&mut arena); 559 | /// // arena 560 | /// // |-- (implicit) 561 | /// // | `-- 1 562 | /// // | |-- 1_1 563 | /// // | | `-- 1_1_1 564 | /// // | `-- 1_3 565 | /// // `-- (implicit) 566 | /// // `-- 1_2 * 567 | /// 568 | /// assert!(arena[n1_2].parent().is_none()); 569 | /// assert!(arena[n1_2].previous_sibling().is_none()); 570 | /// assert!(arena[n1_2].next_sibling().is_none()); 571 | /// 572 | /// let mut iter = n1.descendants(&arena); 573 | /// assert_eq!(iter.next(), Some(n1)); 574 | /// assert_eq!(iter.next(), Some(n1_1)); 575 | /// assert_eq!(iter.next(), Some(n1_1_1)); 576 | /// assert_eq!(iter.next(), Some(n1_3)); 577 | /// assert_eq!(iter.next(), None); 578 | /// ``` 579 | pub fn detach(self, arena: &mut Arena) { 580 | let range = SiblingsRange::new(self, self).detach_from_siblings(arena); 581 | range 582 | .rewrite_parents(arena, None) 583 | .expect("Should never happen: `None` as parent is always valid"); 584 | 585 | // Ensure the node is surely detached. 586 | debug_assert!( 587 | arena[self].is_detached(), 588 | "The node should be successfully detached" 589 | ); 590 | } 591 | 592 | /// Appends a new child to this node, after existing children. 593 | /// 594 | /// # Panics 595 | /// 596 | /// Panics if: 597 | /// 598 | /// * the given new child is `self`, or 599 | /// * the given new child is an ancestor of `self`, or 600 | /// * the current node or the given new child was already [`remove`]d. 601 | /// 602 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 603 | /// 604 | /// # Examples 605 | /// 606 | /// ``` 607 | /// # use indextree::Arena; 608 | /// let mut arena = Arena::new(); 609 | /// let n1 = arena.new_node("1"); 610 | /// let n1_1 = arena.new_node("1_1"); 611 | /// n1.append(n1_1, &mut arena); 612 | /// let n1_2 = arena.new_node("1_2"); 613 | /// n1.append(n1_2, &mut arena); 614 | /// let n1_3 = arena.new_node("1_3"); 615 | /// n1.append(n1_3, &mut arena); 616 | /// 617 | /// // arena 618 | /// // `-- 1 619 | /// // |-- 1_1 620 | /// // |-- 1_2 621 | /// // `-- 1_3 622 | /// 623 | /// let mut iter = n1.descendants(&arena); 624 | /// assert_eq!(iter.next(), Some(n1)); 625 | /// assert_eq!(iter.next(), Some(n1_1)); 626 | /// assert_eq!(iter.next(), Some(n1_2)); 627 | /// assert_eq!(iter.next(), Some(n1_3)); 628 | /// assert_eq!(iter.next(), None); 629 | /// ``` 630 | /// 631 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 632 | /// [`remove`]: struct.NodeId.html#method.remove 633 | pub fn append(self, new_child: NodeId, arena: &mut Arena) { 634 | self.checked_append(new_child, arena) 635 | .expect("Preconditions not met: invalid argument"); 636 | } 637 | 638 | /// Appends a new child to this node, after existing children. 639 | /// 640 | /// # Failures 641 | /// 642 | /// * Returns [`NodeError::AppendSelf`] error if the given new child is 643 | /// `self`. 644 | /// * Returns [`NodeError::AppendAncestor`] error if the given new child is 645 | /// an ancestor of `self`. 646 | /// * Returns [`NodeError::Removed`] error if the given new child or `self` 647 | /// is [`remove`]d. 648 | /// 649 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 650 | /// 651 | /// # Examples 652 | /// 653 | /// ``` 654 | /// # use indextree::Arena; 655 | /// let mut arena = Arena::new(); 656 | /// let n1 = arena.new_node("1"); 657 | /// assert!(n1.checked_append(n1, &mut arena).is_err()); 658 | /// 659 | /// let n1_1 = arena.new_node("1_1"); 660 | /// assert!(n1.checked_append(n1_1, &mut arena).is_ok()); 661 | /// ``` 662 | /// 663 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 664 | /// [`NodeError::AppendSelf`]: enum.NodeError.html#variant.AppendSelf 665 | /// [`NodeError::Removed`]: enum.NodeError.html#variant.Removed 666 | /// [`remove`]: struct.NodeId.html#method.remove 667 | pub fn checked_append( 668 | self, 669 | new_child: NodeId, 670 | arena: &mut Arena, 671 | ) -> Result<(), NodeError> { 672 | if new_child == self { 673 | return Err(NodeError::AppendSelf); 674 | } 675 | if arena[self].is_removed() || arena[new_child].is_removed() { 676 | return Err(NodeError::Removed); 677 | } 678 | if self.ancestors(arena).any(|ancestor| new_child == ancestor) { 679 | return Err(NodeError::AppendAncestor); 680 | } 681 | new_child.detach(arena); 682 | insert_with_neighbors(arena, new_child, Some(self), arena[self].last_child, None) 683 | .expect("Should never fail: `new_child` is not `self` and they are not removed"); 684 | 685 | Ok(()) 686 | } 687 | 688 | /// Creates and appends a new node (from its associated data) as the last child. 689 | /// This method is a fast path for the common case of appending a new node. It is quicker than [`append`]. 690 | /// 691 | /// # Panics 692 | /// 693 | /// Panics if the arena already has `usize::max_value()` nodes. 694 | /// 695 | /// # Examples 696 | /// 697 | /// ``` 698 | /// # use indextree::Arena; 699 | /// let mut arena = Arena::new(); 700 | /// let n1 = arena.new_node("1"); 701 | /// let n1_1 = n1.append_value("1_1", &mut arena); 702 | /// let n1_1_1 = n1_1.append_value("1_1_1", &mut arena); 703 | /// let n1_1_2 = n1_1.append_value("1_1_2", &mut arena); 704 | /// 705 | /// // arena 706 | /// // `-- 1 707 | /// // |-- 1_1 708 | /// // 1_1_1 --|-- 1_1_2 709 | /// 710 | /// let mut iter = n1.descendants(&arena); 711 | /// assert_eq!(iter.next(), Some(n1)); 712 | /// assert_eq!(iter.next(), Some(n1_1)); 713 | /// assert_eq!(iter.next(), Some(n1_1_1)); 714 | /// assert_eq!(iter.next(), Some(n1_1_2)); 715 | /// assert_eq!(iter.next(), None); 716 | /// ``` 717 | /// [`append`]: struct.NodeId.html#method.append 718 | pub fn append_value(self, value: T, arena: &mut Arena) -> NodeId { 719 | let new_child = arena.new_node(value); 720 | self.append_new_node_unchecked(new_child, arena); 721 | 722 | new_child 723 | } 724 | 725 | /// Appends a new child to this node, after all existing children (if any). 726 | /// This method is a fast path for the common case of appending a new node. 727 | /// `new_child` requirements: 728 | /// 1. Must be detached. No parents or siblings. 729 | /// 2. Has not been [`remove`]d. 730 | /// 3. `append_new_node()` was not called on itself 731 | /// 732 | /// # Examples 733 | /// 734 | /// ``` 735 | /// # use indextree::Arena; 736 | /// let mut arena = Arena::new(); 737 | /// let n1 = arena.new_node("1"); 738 | /// assert!(n1.checked_append(n1, &mut arena).is_err()); 739 | /// 740 | /// let n1_1 = arena.new_node("1_1"); 741 | /// assert!(n1.checked_append(n1_1, &mut arena).is_ok()); 742 | /// ``` 743 | /// 744 | /// [`remove`]: struct.NodeId.html#method.remove 745 | fn append_new_node_unchecked(self, new_child: NodeId, arena: &mut Arena) { 746 | insert_last_unchecked(arena, new_child, self); 747 | } 748 | 749 | /// Prepends a new child to this node, before existing children. 750 | /// 751 | /// # Panics 752 | /// 753 | /// Panics if: 754 | /// 755 | /// * the given new child is `self`, or 756 | /// * the given new child is an ancestor of `self`, or 757 | /// * the current node or the given new child was already [`remove`]d. 758 | /// 759 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 760 | /// 761 | /// # Examples 762 | /// 763 | /// ``` 764 | /// # use indextree::Arena; 765 | /// let mut arena = Arena::new(); 766 | /// let n1 = arena.new_node("1"); 767 | /// let n1_1 = arena.new_node("1_1"); 768 | /// n1.prepend(n1_1, &mut arena); 769 | /// let n1_2 = arena.new_node("1_2"); 770 | /// n1.prepend(n1_2, &mut arena); 771 | /// let n1_3 = arena.new_node("1_3"); 772 | /// n1.prepend(n1_3, &mut arena); 773 | /// 774 | /// // arena 775 | /// // `-- 1 776 | /// // |-- 1_3 777 | /// // |-- 1_2 778 | /// // `-- 1_1 779 | /// 780 | /// let mut iter = n1.descendants(&arena); 781 | /// assert_eq!(iter.next(), Some(n1)); 782 | /// assert_eq!(iter.next(), Some(n1_3)); 783 | /// assert_eq!(iter.next(), Some(n1_2)); 784 | /// assert_eq!(iter.next(), Some(n1_1)); 785 | /// assert_eq!(iter.next(), None); 786 | /// ``` 787 | /// 788 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 789 | /// [`remove`]: struct.NodeId.html#method.remove 790 | pub fn prepend(self, new_child: NodeId, arena: &mut Arena) { 791 | self.checked_prepend(new_child, arena) 792 | .expect("Preconditions not met: invalid argument"); 793 | } 794 | 795 | /// Prepends a new child to this node, before existing children. 796 | /// 797 | /// # Failures 798 | /// 799 | /// * Returns [`NodeError::PrependSelf`] error if the given new child is 800 | /// `self`. 801 | /// * Returns [`NodeError::PrependAncestor`] error if the given new child is 802 | /// an ancestor of `self`. 803 | /// * Returns [`NodeError::Removed`] error if the given new child or `self` 804 | /// is [`remove`]d. 805 | /// 806 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 807 | /// 808 | /// # Examples 809 | /// 810 | /// ``` 811 | /// # use indextree::Arena; 812 | /// let mut arena = Arena::new(); 813 | /// let n1 = arena.new_node("1"); 814 | /// assert!(n1.checked_prepend(n1, &mut arena).is_err()); 815 | /// 816 | /// let n1_1 = arena.new_node("1_1"); 817 | /// assert!(n1.checked_prepend(n1_1, &mut arena).is_ok()); 818 | /// ``` 819 | /// 820 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 821 | /// [`NodeError::PrependSelf`]: enum.NodeError.html#variant.PrependSelf 822 | /// [`NodeError::Removed`]: enum.NodeError.html#variant.Removed 823 | /// [`remove`]: struct.NodeId.html#method.remove 824 | pub fn checked_prepend( 825 | self, 826 | new_child: NodeId, 827 | arena: &mut Arena, 828 | ) -> Result<(), NodeError> { 829 | if new_child == self { 830 | return Err(NodeError::PrependSelf); 831 | } 832 | if arena[self].is_removed() || arena[new_child].is_removed() { 833 | return Err(NodeError::Removed); 834 | } 835 | if self.ancestors(arena).any(|ancestor| new_child == ancestor) { 836 | return Err(NodeError::PrependAncestor); 837 | } 838 | insert_with_neighbors(arena, new_child, Some(self), None, arena[self].first_child) 839 | .expect("Should never fail: `new_child` is not `self` and they are not removed"); 840 | 841 | Ok(()) 842 | } 843 | 844 | /// Inserts a new sibling after this node. 845 | /// 846 | /// # Panics 847 | /// 848 | /// Panics if: 849 | /// 850 | /// * the given new sibling is `self`, or 851 | /// * the current node or the given new sibling was already [`remove`]d. 852 | /// 853 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 854 | /// 855 | /// # Examples 856 | /// 857 | /// ``` 858 | /// # use indextree::Arena; 859 | /// # let mut arena = Arena::new(); 860 | /// # let n1 = arena.new_node("1"); 861 | /// # let n1_1 = arena.new_node("1_1"); 862 | /// # n1.append(n1_1, &mut arena); 863 | /// # let n1_2 = arena.new_node("1_2"); 864 | /// # n1.append(n1_2, &mut arena); 865 | /// # 866 | /// // arena 867 | /// // `-- 1 868 | /// // |-- 1_1 * 869 | /// // `-- 1_2 870 | /// 871 | /// let n1_3 = arena.new_node("1_3"); 872 | /// n1_1.insert_after(n1_3, &mut arena); 873 | /// 874 | /// // arena 875 | /// // `-- 1 876 | /// // |-- 1_1 877 | /// // |-- 1_3 * 878 | /// // `-- 1_2 879 | /// 880 | /// let mut iter = n1.descendants(&arena); 881 | /// assert_eq!(iter.next(), Some(n1)); 882 | /// assert_eq!(iter.next(), Some(n1_1)); 883 | /// assert_eq!(iter.next(), Some(n1_3)); 884 | /// assert_eq!(iter.next(), Some(n1_2)); 885 | /// assert_eq!(iter.next(), None); 886 | /// ``` 887 | /// 888 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 889 | /// [`remove`]: struct.NodeId.html#method.remove 890 | pub fn insert_after(self, new_sibling: NodeId, arena: &mut Arena) { 891 | self.checked_insert_after(new_sibling, arena) 892 | .expect("Preconditions not met: invalid argument"); 893 | } 894 | 895 | /// Inserts a new sibling after this node. 896 | /// 897 | /// # Failures 898 | /// 899 | /// * Returns [`NodeError::InsertAfterSelf`] error if the given new sibling 900 | /// is `self`. 901 | /// * Returns [`NodeError::Removed`] error if the given new sibling or 902 | /// `self` is [`remove`]d. 903 | /// 904 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 905 | /// 906 | /// # Examples 907 | /// 908 | /// ``` 909 | /// # use indextree::Arena; 910 | /// let mut arena = Arena::new(); 911 | /// let n1 = arena.new_node("1"); 912 | /// assert!(n1.checked_insert_after(n1, &mut arena).is_err()); 913 | /// 914 | /// let n2 = arena.new_node("2"); 915 | /// assert!(n1.checked_insert_after(n2, &mut arena).is_ok()); 916 | /// ``` 917 | /// 918 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 919 | /// [`NodeError::InsertAfterSelf`]: enum.NodeError.html#variant.InsertAfterSelf 920 | /// [`NodeError::Removed`]: enum.NodeError.html#variant.Removed 921 | /// [`remove`]: struct.NodeId.html#method.remove 922 | pub fn checked_insert_after( 923 | self, 924 | new_sibling: NodeId, 925 | arena: &mut Arena, 926 | ) -> Result<(), NodeError> { 927 | if new_sibling == self { 928 | return Err(NodeError::InsertAfterSelf); 929 | } 930 | if arena[self].is_removed() || arena[new_sibling].is_removed() { 931 | return Err(NodeError::Removed); 932 | } 933 | new_sibling.detach(arena); 934 | let (next_sibling, parent) = { 935 | let current = &arena[self]; 936 | (current.next_sibling, current.parent) 937 | }; 938 | insert_with_neighbors(arena, new_sibling, parent, Some(self), next_sibling) 939 | .expect("Should never fail: `new_sibling` is not `self` and they are not removed"); 940 | 941 | Ok(()) 942 | } 943 | 944 | /// Inserts a new sibling before this node. 945 | /// 946 | /// # Panics 947 | /// 948 | /// Panics if: 949 | /// 950 | /// * the given new sibling is `self`, or 951 | /// * the current node or the given new sibling was already [`remove`]d. 952 | /// 953 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 954 | /// 955 | /// # Examples 956 | /// 957 | /// ``` 958 | /// # use indextree::Arena; 959 | /// let mut arena = Arena::new(); 960 | /// let n1 = arena.new_node("1"); 961 | /// let n1_1 = arena.new_node("1_1"); 962 | /// n1.append(n1_1, &mut arena); 963 | /// let n1_2 = arena.new_node("1_2"); 964 | /// n1.append(n1_2, &mut arena); 965 | /// 966 | /// // arena 967 | /// // `-- 1 968 | /// // |-- 1_1 969 | /// // `-- 1_2 * 970 | /// 971 | /// let n1_3 = arena.new_node("1_3"); 972 | /// n1_2.insert_before(n1_3, &mut arena); 973 | /// 974 | /// // arena 975 | /// // `-- 1 976 | /// // |-- 1_1 977 | /// // |-- 1_3 * 978 | /// // `-- 1_2 979 | /// 980 | /// let mut iter = n1.descendants(&arena); 981 | /// assert_eq!(iter.next(), Some(n1)); 982 | /// assert_eq!(iter.next(), Some(n1_1)); 983 | /// assert_eq!(iter.next(), Some(n1_3)); 984 | /// assert_eq!(iter.next(), Some(n1_2)); 985 | /// assert_eq!(iter.next(), None); 986 | /// ``` 987 | /// 988 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 989 | /// [`remove`]: struct.NodeId.html#method.remove 990 | pub fn insert_before(self, new_sibling: NodeId, arena: &mut Arena) { 991 | self.checked_insert_before(new_sibling, arena) 992 | .expect("Preconditions not met: invalid argument"); 993 | } 994 | 995 | /// Inserts a new sibling before this node. 996 | /// 997 | /// # Failures 998 | /// 999 | /// * Returns [`NodeError::InsertBeforeSelf`] error if the given new sibling 1000 | /// is `self`. 1001 | /// * Returns [`NodeError::Removed`] error if the given new sibling or 1002 | /// `self` is [`remove`]d. 1003 | /// 1004 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 1005 | /// 1006 | /// # Examples 1007 | /// 1008 | /// ``` 1009 | /// # use indextree::Arena; 1010 | /// let mut arena = Arena::new(); 1011 | /// let n1 = arena.new_node("1"); 1012 | /// assert!(n1.checked_insert_before(n1, &mut arena).is_err()); 1013 | /// 1014 | /// let n2 = arena.new_node("2"); 1015 | /// assert!(n1.checked_insert_before(n2, &mut arena).is_ok()); 1016 | /// ``` 1017 | /// 1018 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 1019 | /// [`NodeError::InsertBeforeSelf`]: enum.NodeError.html#variant.InsertBeforeSelf 1020 | /// [`NodeError::Removed`]: enum.NodeError.html#variant.Removed 1021 | /// [`remove`]: struct.NodeId.html#method.remove 1022 | pub fn checked_insert_before( 1023 | self, 1024 | new_sibling: NodeId, 1025 | arena: &mut Arena, 1026 | ) -> Result<(), NodeError> { 1027 | if new_sibling == self { 1028 | return Err(NodeError::InsertBeforeSelf); 1029 | } 1030 | if arena[self].is_removed() || arena[new_sibling].is_removed() { 1031 | return Err(NodeError::Removed); 1032 | } 1033 | new_sibling.detach(arena); 1034 | let (previous_sibling, parent) = { 1035 | let current = &arena[self]; 1036 | (current.previous_sibling, current.parent) 1037 | }; 1038 | insert_with_neighbors(arena, new_sibling, parent, previous_sibling, Some(self)) 1039 | .expect("Should never fail: `new_sibling` is not `self` and they are not removed"); 1040 | 1041 | Ok(()) 1042 | } 1043 | 1044 | /// Removes a node from the arena. 1045 | /// 1046 | /// Children of the removed node will be inserted to the place where the 1047 | /// removed node was. 1048 | /// 1049 | /// Please note that the node will not be removed from the internal arena 1050 | /// storage, but marked as `removed`. Traversing the arena returns a 1051 | /// plain iterator and contains removed elements too. 1052 | /// 1053 | /// To check if the node is removed or not, use [`Node::is_removed()`]. 1054 | /// 1055 | /// # Examples 1056 | /// 1057 | /// ``` 1058 | /// # use indextree::Arena; 1059 | /// # let mut arena = Arena::new(); 1060 | /// # let n1 = arena.new_node("1"); 1061 | /// # let n1_1 = arena.new_node("1_1"); 1062 | /// # n1.append(n1_1, &mut arena); 1063 | /// # let n1_2 = arena.new_node("1_2"); 1064 | /// # n1.append(n1_2, &mut arena); 1065 | /// # let n1_2_1 = arena.new_node("1_2_1"); 1066 | /// # n1_2.append(n1_2_1, &mut arena); 1067 | /// # let n1_2_2 = arena.new_node("1_2_2"); 1068 | /// # n1_2.append(n1_2_2, &mut arena); 1069 | /// # let n1_3 = arena.new_node("1_3"); 1070 | /// # n1.append(n1_3, &mut arena); 1071 | /// # 1072 | /// // arena 1073 | /// // `-- 1 1074 | /// // |-- 1_1 1075 | /// // |-- 1_2 * 1076 | /// // | |-- 1_2_1 1077 | /// // | `-- 1_2_2 1078 | /// // `-- 1_3 1079 | /// 1080 | /// n1_2.remove(&mut arena); 1081 | /// 1082 | /// // arena 1083 | /// // `-- 1 1084 | /// // |-- 1_1 1085 | /// // |-- 1_2_1 1086 | /// // |-- 1_2_2 1087 | /// // `-- 1_3 1088 | /// 1089 | /// let mut iter = n1.descendants(&arena); 1090 | /// assert_eq!(iter.next(), Some(n1)); 1091 | /// assert_eq!(iter.next(), Some(n1_1)); 1092 | /// assert_eq!(iter.next(), Some(n1_2_1)); 1093 | /// assert_eq!(iter.next(), Some(n1_2_2)); 1094 | /// assert_eq!(iter.next(), Some(n1_3)); 1095 | /// assert_eq!(iter.next(), None); 1096 | /// ``` 1097 | /// 1098 | /// [`Node::is_removed()`]: struct.Node.html#method.is_removed 1099 | pub fn remove(self, arena: &mut Arena) { 1100 | debug_assert_triangle_nodes!( 1101 | arena, 1102 | arena[self].parent, 1103 | arena[self].previous_sibling, 1104 | Some(self) 1105 | ); 1106 | debug_assert_triangle_nodes!( 1107 | arena, 1108 | arena[self].parent, 1109 | Some(self), 1110 | arena[self].next_sibling 1111 | ); 1112 | debug_assert_triangle_nodes!(arena, Some(self), None, arena[self].first_child); 1113 | debug_assert_triangle_nodes!(arena, Some(self), arena[self].last_child, None); 1114 | 1115 | // Retrieve needed values. 1116 | let (parent, previous_sibling, next_sibling, first_child, last_child) = { 1117 | let node = &arena[self]; 1118 | ( 1119 | node.parent, 1120 | node.previous_sibling, 1121 | node.next_sibling, 1122 | node.first_child, 1123 | node.last_child, 1124 | ) 1125 | }; 1126 | 1127 | assert_eq!(first_child.is_some(), last_child.is_some()); 1128 | self.detach(arena); 1129 | if let (Some(first_child), Some(last_child)) = (first_child, last_child) { 1130 | let range = SiblingsRange::new(first_child, last_child).detach_from_siblings(arena); 1131 | range 1132 | .transplant(arena, parent, previous_sibling, next_sibling) 1133 | .expect("Should never fail: neighbors and children must be consistent"); 1134 | } 1135 | arena.free_node(self); 1136 | debug_assert!(arena[self].is_detached()); 1137 | } 1138 | 1139 | /// Removes a node and its descendants from the arena. 1140 | /// # Examples 1141 | /// 1142 | /// ``` 1143 | /// # use indextree::Arena; 1144 | /// # let mut arena = Arena::new(); 1145 | /// # let n1 = arena.new_node("1"); 1146 | /// # let n1_1 = arena.new_node("1_1"); 1147 | /// # n1.append(n1_1, &mut arena); 1148 | /// # let n1_2 = arena.new_node("1_2"); 1149 | /// # n1.append(n1_2, &mut arena); 1150 | /// # let n1_2_1 = arena.new_node("1_2_1"); 1151 | /// # n1_2.append(n1_2_1, &mut arena); 1152 | /// # let n1_2_2 = arena.new_node("1_2_2"); 1153 | /// # n1_2.append(n1_2_2, &mut arena); 1154 | /// # let n1_3 = arena.new_node("1_3"); 1155 | /// # n1.append(n1_3, &mut arena); 1156 | /// # 1157 | /// // arena 1158 | /// // `-- 1 1159 | /// // |-- 1_1 1160 | /// // |-- 1_2 * 1161 | /// // | |-- 1_2_1 1162 | /// // | `-- 1_2_2 1163 | /// // `-- 1_3 1164 | /// 1165 | /// n1_2.remove_subtree(&mut arena); 1166 | /// 1167 | /// // arena 1168 | /// // `-- 1 1169 | /// // |-- 1_1 1170 | /// // `-- 1_3 1171 | /// 1172 | /// let mut iter = n1.descendants(&arena); 1173 | /// assert_eq!(iter.next(), Some(n1)); 1174 | /// assert_eq!(iter.next(), Some(n1_1)); 1175 | /// assert_eq!(iter.next(), Some(n1_3)); 1176 | /// assert_eq!(iter.next(), None); 1177 | /// ``` 1178 | /// 1179 | pub fn remove_subtree(self, arena: &mut Arena) { 1180 | self.detach(arena); 1181 | 1182 | // use a preorder traversal to remove node. 1183 | let mut cursor = Some(self); 1184 | while let Some(id) = cursor { 1185 | arena.free_node(id); 1186 | let node = &arena[id]; 1187 | cursor = node.first_child.or(node.next_sibling).or_else(|| { 1188 | id.ancestors(arena) // traverse ancestors upwards 1189 | .skip(1) // skip the starting node itself 1190 | .find(|n| arena[*n].next_sibling.is_some()) // first ancestor with a sibling 1191 | .and_then(|n| arena[n].next_sibling) // the sibling is the new cursor 1192 | }); 1193 | } 1194 | } 1195 | 1196 | /// Returns the pretty-printable proxy object to the node and descendants. 1197 | /// 1198 | /// # (No) guarantees 1199 | /// 1200 | /// This is provided mainly for debugging purpose. Node that the output 1201 | /// format is not guaranteed to be stable, and any format changes won't be 1202 | /// considered as breaking changes. 1203 | /// 1204 | /// # Examples 1205 | /// 1206 | /// ``` 1207 | /// # use indextree::Arena; 1208 | /// # 1209 | /// # let mut arena = Arena::new(); 1210 | /// # let root = arena.new_node("root"); 1211 | /// # let n0 = arena.new_node("0"); 1212 | /// # root.append(n0, &mut arena); 1213 | /// # let n0_0 = arena.new_node("0\n0"); 1214 | /// # n0.append(n0_0, &mut arena); 1215 | /// # let n0_1 = arena.new_node("0\n1"); 1216 | /// # n0.append(n0_1, &mut arena); 1217 | /// # let n1 = arena.new_node("1"); 1218 | /// # root.append(n1, &mut arena); 1219 | /// # let n2 = arena.new_node("2"); 1220 | /// # root.append(n2, &mut arena); 1221 | /// # let n2_0 = arena.new_node("2\n0"); 1222 | /// # n2.append(n2_0, &mut arena); 1223 | /// # let n2_0_0 = arena.new_node("2\n0\n0"); 1224 | /// # n2_0.append(n2_0_0, &mut arena); 1225 | /// 1226 | /// // arena 1227 | /// // `-- "root" 1228 | /// // |-- "0" 1229 | /// // | |-- "0\n0" 1230 | /// // | `-- "0\n1" 1231 | /// // |-- "1" 1232 | /// // `-- "2" 1233 | /// // `-- "2\n0" 1234 | /// // `-- "2\n0\n0" 1235 | /// 1236 | /// let printable = root.debug_pretty_print(&arena); 1237 | /// 1238 | /// let expected_debug = r#""root" 1239 | /// |-- "0" 1240 | /// | |-- "0\n0" 1241 | /// | `-- "0\n1" 1242 | /// |-- "1" 1243 | /// `-- "2" 1244 | /// `-- "2\n0" 1245 | /// `-- "2\n0\n0""#; 1246 | /// assert_eq!(format!("{:?}", printable), expected_debug); 1247 | /// 1248 | /// let expected_display = r#"root 1249 | /// |-- 0 1250 | /// | |-- 0 1251 | /// | | 0 1252 | /// | `-- 0 1253 | /// | 1 1254 | /// |-- 1 1255 | /// `-- 2 1256 | /// `-- 2 1257 | /// 0 1258 | /// `-- 2 1259 | /// 0 1260 | /// 0"#; 1261 | /// assert_eq!(printable.to_string(), expected_display); 1262 | /// ``` 1263 | /// 1264 | /// Alternate styles (`{:#?}` and `{:#}`) are also supported. 1265 | /// 1266 | /// ``` 1267 | /// # use indextree::Arena; 1268 | /// # 1269 | /// # let mut arena = Arena::new(); 1270 | /// # let root = arena.new_node(Ok(42)); 1271 | /// # let child = arena.new_node(Err("err")); 1272 | /// # root.append(child, &mut arena); 1273 | /// 1274 | /// // arena 1275 | /// // `-- Ok(42) 1276 | /// // `-- Err("err") 1277 | /// 1278 | /// let printable = root.debug_pretty_print(&arena); 1279 | /// 1280 | /// let expected_debug = r#"Ok(42) 1281 | /// `-- Err("err")"#; 1282 | /// assert_eq!(format!("{:?}", printable), expected_debug); 1283 | /// 1284 | /// let expected_debug_alternate = r#"Ok( 1285 | /// 42, 1286 | /// ) 1287 | /// `-- Err( 1288 | /// "err", 1289 | /// )"#; 1290 | /// assert_eq!(format!("{:#?}", printable), expected_debug_alternate); 1291 | /// ``` 1292 | #[inline] 1293 | #[must_use] 1294 | pub fn debug_pretty_print<'a, T>(&'a self, arena: &'a Arena) -> DebugPrettyPrint<'a, T> { 1295 | DebugPrettyPrint::new(self, arena) 1296 | } 1297 | } 1298 | 1299 | #[cfg(test)] 1300 | mod tests { 1301 | use super::*; 1302 | 1303 | #[test] 1304 | fn test_remove_subtree_complex() { 1305 | // arena 1306 | // `-- 1 1307 | // |-- 1_1 1308 | // |-- 1_2 1309 | // | |-- 1_2_1 1310 | // | | `-- 1_2_1_1 1311 | // | | `-- 1_2_1_1_1 1312 | // | `-- 1_2_2 1313 | // `-- 1_3 1314 | let mut arena = Arena::new(); 1315 | let n1 = arena.new_node("1"); 1316 | let n1_1 = arena.new_node("1_1"); 1317 | n1.append(n1_1, &mut arena); 1318 | let n1_2 = arena.new_node("1_2"); 1319 | n1.append(n1_2, &mut arena); 1320 | let n1_2_1 = arena.new_node("1_2_1"); 1321 | n1_2.append(n1_2_1, &mut arena); 1322 | let n1_2_1_1 = arena.new_node("1_2_1_1"); 1323 | n1_2_1.append(n1_2_1_1, &mut arena); 1324 | let n1_2_1_1_1 = arena.new_node("1_2_1_1_1"); 1325 | n1_2_1_1.append(n1_2_1_1_1, &mut arena); 1326 | let n1_2_2 = arena.new_node("1_2_2"); 1327 | n1_2.append(n1_2_2, &mut arena); 1328 | let n1_3 = arena.new_node("1_3"); 1329 | n1.append(n1_3, &mut arena); 1330 | 1331 | n1_2.remove_subtree(&mut arena); 1332 | 1333 | assert!(!n1.is_removed(&arena)); 1334 | assert!(!n1_1.is_removed(&arena)); 1335 | assert!(!n1_3.is_removed(&arena)); 1336 | 1337 | assert!(n1_2.is_removed(&arena)); 1338 | assert!(n1_2_1.is_removed(&arena)); 1339 | assert!(n1_2_1_1.is_removed(&arena)); 1340 | assert!(n1_2_1_1_1.is_removed(&arena)); 1341 | assert!(n1_2_2.is_removed(&arena)); 1342 | } 1343 | 1344 | #[test] 1345 | fn test_conversions() { 1346 | let mut arena = Arena::new(); 1347 | let n1 = arena.new_node("1"); 1348 | assert_eq!(usize::from(n1), 1); 1349 | assert_eq!(NonZeroUsize::from(n1), NonZeroUsize::new(1).unwrap()); 1350 | assert_eq!(n1.to_string(), "1"); 1351 | } 1352 | } 1353 | -------------------------------------------------------------------------------- /indextree/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Arena based tree data structure 2 | //! 3 | //! This arena tree structure is using just a single `Vec` and numerical 4 | //! identifiers (indices in the vector) instead of reference counted pointers 5 | //! like. This means there is no `RefCell` and mutability is handled in a way 6 | //! much more idiomatic to Rust through unique (&mut) access to the arena. The 7 | //! tree can be sent or shared across threads like a `Vec`. This enables 8 | //! general multiprocessing support like parallel tree traversals. 9 | //! 10 | //! # Example usage 11 | //! ``` 12 | //! use indextree::Arena; 13 | //! 14 | //! // Create a new arena 15 | //! let arena = &mut Arena::new(); 16 | //! 17 | //! // Add some new nodes to the arena 18 | //! let a = arena.new_node(1); 19 | //! let b = arena.new_node(2); 20 | //! 21 | //! // Append b to a 22 | //! a.append(b, arena); 23 | //! assert_eq!(b.ancestors(arena).into_iter().count(), 2); 24 | //! ``` 25 | #![forbid(unsafe_code)] 26 | #![cfg_attr(not(feature = "std"), no_std)] 27 | 28 | #[cfg(not(feature = "std"))] 29 | extern crate alloc; 30 | 31 | #[allow(deprecated)] 32 | pub use crate::{ 33 | arena::Arena, 34 | debug_pretty_print::DebugPrettyPrint, 35 | error::NodeError, 36 | id::NodeId, 37 | node::Node, 38 | traverse::{ 39 | Ancestors, Children, Descendants, FollowingSiblings, NodeEdge, PrecedingSiblings, 40 | Predecessors, ReverseChildren, ReverseTraverse, Traverse, 41 | }, 42 | }; 43 | 44 | #[cfg(feature = "macros")] 45 | pub use indextree_macros as macros; 46 | 47 | #[macro_use] 48 | pub(crate) mod relations; 49 | 50 | mod arena; 51 | mod debug_pretty_print; 52 | pub(crate) mod error; 53 | mod id; 54 | mod node; 55 | pub(crate) mod siblings_range; 56 | mod traverse; 57 | -------------------------------------------------------------------------------- /indextree/src/node.rs: -------------------------------------------------------------------------------- 1 | //! Node. 2 | 3 | #[cfg(not(feature = "std"))] 4 | use core::fmt; 5 | 6 | #[cfg(feature = "deser")] 7 | use serde::{Deserialize, Serialize}; 8 | 9 | #[cfg(feature = "std")] 10 | use std::fmt; 11 | 12 | use crate::{id::NodeStamp, NodeId}; 13 | 14 | #[derive(PartialEq, Eq, Clone, Debug)] 15 | #[cfg_attr(feature = "deser", derive(Deserialize, Serialize))] 16 | pub(crate) enum NodeData { 17 | /// The actual data store 18 | Data(T), 19 | /// The next free node position. 20 | NextFree(Option), 21 | } 22 | 23 | #[derive(PartialEq, Eq, Clone, Debug)] 24 | #[cfg_attr(feature = "deser", derive(Deserialize, Serialize))] 25 | /// A node within a particular `Arena`. 26 | pub struct Node { 27 | // Keep these private (with read-only accessors) so that we can keep them 28 | // consistent. E.g. the parent of a node’s child is that node. 29 | pub(crate) parent: Option, 30 | pub(crate) previous_sibling: Option, 31 | pub(crate) next_sibling: Option, 32 | pub(crate) first_child: Option, 33 | pub(crate) last_child: Option, 34 | pub(crate) stamp: NodeStamp, 35 | /// The actual data which will be stored within the tree. 36 | pub(crate) data: NodeData, 37 | } 38 | 39 | impl Node { 40 | /// Returns a reference to the node data. 41 | pub fn get(&self) -> &T { 42 | if let NodeData::Data(ref data) = self.data { 43 | data 44 | } else { 45 | unreachable!("Try to access a freed node") 46 | } 47 | } 48 | 49 | /// Returns a mutable reference to the node data. 50 | pub fn get_mut(&mut self) -> &mut T { 51 | if let NodeData::Data(ref mut data) = self.data { 52 | data 53 | } else { 54 | unreachable!("Try to access a freed node") 55 | } 56 | } 57 | 58 | /// Creates a new `Node` with the default state and the given data. 59 | pub(crate) fn new(data: T) -> Self { 60 | Self { 61 | parent: None, 62 | previous_sibling: None, 63 | next_sibling: None, 64 | first_child: None, 65 | last_child: None, 66 | stamp: NodeStamp::default(), 67 | data: NodeData::Data(data), 68 | } 69 | } 70 | 71 | /// Convert a removed `Node` to normal with default state and given data. 72 | pub(crate) fn reuse(&mut self, data: T) { 73 | debug_assert!(matches!(self.data, NodeData::NextFree(_))); 74 | debug_assert!(self.stamp.is_removed()); 75 | self.stamp.reuse(); 76 | self.parent = None; 77 | self.previous_sibling = None; 78 | self.next_sibling = None; 79 | self.first_child = None; 80 | self.last_child = None; 81 | self.data = NodeData::Data(data); 82 | } 83 | 84 | /// Returns the ID of the parent node, unless this node is the root of the 85 | /// tree. 86 | /// 87 | /// # Examples 88 | /// 89 | /// ``` 90 | /// # use indextree::Arena; 91 | /// # let mut arena = Arena::new(); 92 | /// # let n1 = arena.new_node("1"); 93 | /// # let n1_1 = arena.new_node("1_1"); 94 | /// # let n1_2 = arena.new_node("1_2"); 95 | /// # n1.append(n1_2, &mut arena); 96 | /// # let n1_3 = arena.new_node("1_3"); 97 | /// # n1.append(n1_3, &mut arena); 98 | /// # n1.append(n1_1, &mut arena); 99 | /// // arena 100 | /// // `-- 1 101 | /// // |-- 1_1 102 | /// // |-- 1_2 103 | /// // `-- 1_3 104 | /// assert_eq!(arena[n1].parent(), None); 105 | /// assert_eq!(arena[n1_1].parent(), Some(n1)); 106 | /// assert_eq!(arena[n1_2].parent(), Some(n1)); 107 | /// assert_eq!(arena[n1_3].parent(), Some(n1)); 108 | /// ``` 109 | pub fn parent(&self) -> Option { 110 | self.parent 111 | } 112 | 113 | /// Returns the ID of the first child of this node, unless it has no child. 114 | /// 115 | /// # Examples 116 | /// 117 | /// ``` 118 | /// # use indextree::Arena; 119 | /// # let mut arena = Arena::new(); 120 | /// # let n1 = arena.new_node("1"); 121 | /// # let n1_1 = arena.new_node("1_1"); 122 | /// # n1.append(n1_1, &mut arena); 123 | /// # let n1_2 = arena.new_node("1_2"); 124 | /// # n1.append(n1_2, &mut arena); 125 | /// # let n1_3 = arena.new_node("1_3"); 126 | /// # n1.append(n1_3, &mut arena); 127 | /// // arena 128 | /// // `-- 1 129 | /// // |-- 1_1 130 | /// // |-- 1_2 131 | /// // `-- 1_3 132 | /// assert_eq!(arena[n1].first_child(), Some(n1_1)); 133 | /// assert_eq!(arena[n1_1].first_child(), None); 134 | /// assert_eq!(arena[n1_2].first_child(), None); 135 | /// assert_eq!(arena[n1_3].first_child(), None); 136 | /// ``` 137 | pub fn first_child(&self) -> Option { 138 | self.first_child 139 | } 140 | 141 | /// Returns the ID of the last child of this node, unless it has no child. 142 | /// 143 | /// # Examples 144 | /// 145 | /// ``` 146 | /// # use indextree::Arena; 147 | /// # let mut arena = Arena::new(); 148 | /// # let n1 = arena.new_node("1"); 149 | /// # let n1_1 = arena.new_node("1_1"); 150 | /// # n1.append(n1_1, &mut arena); 151 | /// # let n1_2 = arena.new_node("1_2"); 152 | /// # n1.append(n1_2, &mut arena); 153 | /// # let n1_3 = arena.new_node("1_3"); 154 | /// # n1.append(n1_3, &mut arena); 155 | /// // arena 156 | /// // `-- 1 157 | /// // |-- 1_1 158 | /// // |-- 1_2 159 | /// // `-- 1_3 160 | /// assert_eq!(arena[n1].last_child(), Some(n1_3)); 161 | /// assert_eq!(arena[n1_1].last_child(), None); 162 | /// assert_eq!(arena[n1_2].last_child(), None); 163 | /// assert_eq!(arena[n1_3].last_child(), None); 164 | /// ``` 165 | pub fn last_child(&self) -> Option { 166 | self.last_child 167 | } 168 | 169 | /// Returns the ID of the previous sibling of this node, unless it is a 170 | /// first child. 171 | /// 172 | /// # Examples 173 | /// 174 | /// ``` 175 | /// # use indextree::Arena; 176 | /// # let mut arena = Arena::new(); 177 | /// # let n1 = arena.new_node("1"); 178 | /// # let n1_1 = arena.new_node("1_1"); 179 | /// # n1.append(n1_1, &mut arena); 180 | /// # let n1_2 = arena.new_node("1_2"); 181 | /// # n1.append(n1_2, &mut arena); 182 | /// # let n1_3 = arena.new_node("1_3"); 183 | /// # n1.append(n1_3, &mut arena); 184 | /// // arena 185 | /// // `-- 1 186 | /// // |-- 1_1 187 | /// // |-- 1_2 188 | /// // `-- 1_3 189 | /// assert_eq!(arena[n1].previous_sibling(), None); 190 | /// assert_eq!(arena[n1_1].previous_sibling(), None); 191 | /// assert_eq!(arena[n1_2].previous_sibling(), Some(n1_1)); 192 | /// assert_eq!(arena[n1_3].previous_sibling(), Some(n1_2)); 193 | /// ``` 194 | /// 195 | /// Note that newly created nodes are independent toplevel nodes, and they 196 | /// are not siblings by default. 197 | /// 198 | /// ``` 199 | /// # use indextree::Arena; 200 | /// let mut arena = Arena::new(); 201 | /// let n1 = arena.new_node("1"); 202 | /// let n2 = arena.new_node("2"); 203 | /// // arena 204 | /// // |-- (implicit) 205 | /// // | `-- 1 206 | /// // `-- (implicit) 207 | /// // `-- 2 208 | /// assert_eq!(arena[n1].previous_sibling(), None); 209 | /// assert_eq!(arena[n2].previous_sibling(), None); 210 | /// 211 | /// n1.insert_after(n2, &mut arena); 212 | /// // arena 213 | /// // `-- (implicit) 214 | /// // |-- 1 215 | /// // `-- 2 216 | /// assert_eq!(arena[n1].previous_sibling(), None); 217 | /// assert_eq!(arena[n2].previous_sibling(), Some(n1)); 218 | /// ``` 219 | pub fn previous_sibling(&self) -> Option { 220 | self.previous_sibling 221 | } 222 | 223 | /// Returns the ID of the next sibling of this node, unless it is a 224 | /// last child. 225 | /// 226 | /// # Examples 227 | /// 228 | /// ``` 229 | /// # use indextree::Arena; 230 | /// # let mut arena = Arena::new(); 231 | /// # let n1 = arena.new_node("1"); 232 | /// # let n1_1 = arena.new_node("1_1"); 233 | /// # n1.append(n1_1, &mut arena); 234 | /// # let n1_2 = arena.new_node("1_2"); 235 | /// # n1.append(n1_2, &mut arena); 236 | /// # let n1_3 = arena.new_node("1_3"); 237 | /// # n1.append(n1_3, &mut arena); 238 | /// // arena 239 | /// // `-- 1 240 | /// // |-- 1_1 241 | /// // |-- 1_2 242 | /// // `-- 1_3 243 | /// assert_eq!(arena[n1].next_sibling(), None); 244 | /// assert_eq!(arena[n1_1].next_sibling(), Some(n1_2)); 245 | /// assert_eq!(arena[n1_2].next_sibling(), Some(n1_3)); 246 | /// assert_eq!(arena[n1_3].next_sibling(), None); 247 | /// ``` 248 | /// 249 | /// Note that newly created nodes are independent toplevel nodes, and they 250 | /// are not siblings by default. 251 | /// 252 | /// ``` 253 | /// # use indextree::Arena; 254 | /// let mut arena = Arena::new(); 255 | /// let n1 = arena.new_node("1"); 256 | /// let n2 = arena.new_node("2"); 257 | /// // arena 258 | /// // |-- (implicit) 259 | /// // | `-- 1 260 | /// // `-- (implicit) 261 | /// // `-- 2 262 | /// assert_eq!(arena[n1].next_sibling(), None); 263 | /// assert_eq!(arena[n2].next_sibling(), None); 264 | /// 265 | /// n1.insert_after(n2, &mut arena); 266 | /// // arena 267 | /// // `-- (implicit) 268 | /// // |-- 1 269 | /// // `-- 2 270 | /// assert_eq!(arena[n1].next_sibling(), Some(n2)); 271 | /// assert_eq!(arena[n2].next_sibling(), None); 272 | /// ``` 273 | pub fn next_sibling(&self) -> Option { 274 | self.next_sibling 275 | } 276 | 277 | /// Checks if the node is marked as removed. 278 | /// 279 | /// # Examples 280 | /// 281 | /// ``` 282 | /// # use indextree::Arena; 283 | /// # let mut arena = Arena::new(); 284 | /// # let n1 = arena.new_node("1"); 285 | /// # let n1_1 = arena.new_node("1_1"); 286 | /// # n1.append(n1_1, &mut arena); 287 | /// # let n1_2 = arena.new_node("1_2"); 288 | /// # n1.append(n1_2, &mut arena); 289 | /// # let n1_3 = arena.new_node("1_3"); 290 | /// # n1.append(n1_3, &mut arena); 291 | /// // arena 292 | /// // `-- 1 293 | /// // |-- 1_1 294 | /// // |-- 1_2 * 295 | /// // `-- 1_3 296 | /// assert_eq!(arena[n1_1].next_sibling(), Some(n1_2)); 297 | /// assert_eq!(arena[n1_2].parent(), Some(n1)); 298 | /// assert!(!arena[n1_2].is_removed()); 299 | /// assert_eq!(arena[n1_3].previous_sibling(), Some(n1_2)); 300 | /// 301 | /// n1_2.remove(&mut arena); 302 | /// // arena 303 | /// // `-- 1 304 | /// // |-- 1_1 305 | /// // `-- 1_3 306 | /// assert_eq!(arena[n1_1].next_sibling(), Some(n1_3)); 307 | /// assert_eq!(arena[n1_2].parent(), None); 308 | /// assert!(arena[n1_2].is_removed()); 309 | /// assert_eq!(arena[n1_3].previous_sibling(), Some(n1_1)); 310 | /// ``` 311 | pub fn is_removed(&self) -> bool { 312 | self.stamp.is_removed() 313 | } 314 | 315 | /// Checks if the node is detached. 316 | pub(crate) fn is_detached(&self) -> bool { 317 | self.parent.is_none() && self.previous_sibling.is_none() && self.next_sibling.is_none() 318 | } 319 | } 320 | 321 | impl fmt::Display for Node { 322 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 323 | if let Some(parent) = self.parent { 324 | write!(f, "parent: {}; ", parent)?; 325 | } else { 326 | write!(f, "no parent; ")?; 327 | } 328 | if let Some(previous_sibling) = self.previous_sibling { 329 | write!(f, "previous sibling: {}; ", previous_sibling)?; 330 | } else { 331 | write!(f, "no previous sibling; ")?; 332 | } 333 | if let Some(next_sibling) = self.next_sibling { 334 | write!(f, "next sibling: {}; ", next_sibling)?; 335 | } else { 336 | write!(f, "no next sibling; ")?; 337 | } 338 | if let Some(first_child) = self.first_child { 339 | write!(f, "first child: {}; ", first_child)?; 340 | } else { 341 | write!(f, "no first child; ")?; 342 | } 343 | if let Some(last_child) = self.last_child { 344 | write!(f, "last child: {}; ", last_child)?; 345 | } else { 346 | write!(f, "no last child; ")?; 347 | } 348 | Ok(()) 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /indextree/src/relations.rs: -------------------------------------------------------------------------------- 1 | //! Utilities related to nodes relations. 2 | 3 | use crate::{ 4 | error::ConsistencyError, 5 | siblings_range::{DetachedSiblingsRange, SiblingsRange}, 6 | Arena, NodeId, 7 | }; 8 | 9 | /// Ensures the given parent, previous, and next nodes are consistent. 10 | /// 11 | /// This assert is only enabled in debug build. 12 | macro_rules! debug_assert_triangle_nodes { 13 | ($arena:expr, $parent:expr, $previous:expr, $next:expr $(,)?) => {{ 14 | if cfg!(debug_assertions) { 15 | crate::relations::assert_triangle_nodes($arena, $parent, $previous, $next); 16 | } 17 | }}; 18 | } 19 | 20 | /// Ensures the given parent, previous, and next nodes are consistent. 21 | /// 22 | /// # Panics 23 | /// 24 | /// Panics if the given nodes are inconsistent. 25 | pub(crate) fn assert_triangle_nodes( 26 | arena: &Arena, 27 | parent: Option, 28 | previous: Option, 29 | next: Option, 30 | ) { 31 | if let Some(previous_node) = previous.map(|id| &arena[id]) { 32 | assert_eq!( 33 | previous_node.parent, parent, 34 | "`prev->parent` must equal to `parent`" 35 | ); 36 | assert_eq!( 37 | previous_node.next_sibling, next, 38 | "`prev->next` must equal to `next`" 39 | ); 40 | } 41 | if let Some(next_node) = next.map(|id| &arena[id]) { 42 | assert_eq!( 43 | next_node.parent, parent, 44 | "`next->parent` must equal to `parent`" 45 | ); 46 | assert_eq!( 47 | next_node.previous_sibling, previous, 48 | "`next->prev` must equal to `prev`" 49 | ); 50 | } 51 | } 52 | 53 | /// Connects the given adjacent neighbor nodes and update fields properly. 54 | /// 55 | /// This connects the given three nodes (if `Some(_)`) and update fields to make 56 | /// them consistent. 57 | /// 58 | /// ```text 59 | /// parent 60 | /// / \ 61 | /// / \ 62 | /// prev -> next 63 | /// ``` 64 | pub(crate) fn connect_neighbors( 65 | arena: &mut Arena, 66 | parent: Option, 67 | previous: Option, 68 | next: Option, 69 | ) { 70 | if cfg!(debug_assertions) { 71 | if let Some(parent_node) = parent.map(|id| &arena[id]) { 72 | debug_assert_eq!( 73 | parent_node.first_child.is_some(), 74 | parent_node.last_child.is_some() 75 | ); 76 | debug_assert!(!parent_node.is_removed()); 77 | } 78 | debug_assert!(!previous.is_some_and(|id| arena[id].is_removed())); 79 | debug_assert!(!next.is_some_and(|id| arena[id].is_removed())); 80 | } 81 | 82 | let (mut parent_first_child, mut parent_last_child) = parent 83 | .map(|id| &arena[id]) 84 | .map_or((None, None), |node| (node.first_child, node.last_child)); 85 | if let Some(previous) = previous { 86 | // `previous` ==> `next` 87 | arena[previous].next_sibling = next; 88 | parent_first_child = parent_first_child.or(Some(previous)); 89 | } else { 90 | // `next` is the first child of the parent. 91 | parent_first_child = next; 92 | } 93 | if let Some(next) = next { 94 | // `previous` <== `next` 95 | arena[next].previous_sibling = previous; 96 | parent_last_child = parent_last_child.or(Some(next)); 97 | } else { 98 | // `previous` is the last child of the parent. 99 | parent_last_child = previous; 100 | } 101 | 102 | if let Some(parent_node) = parent.map(|id| &mut arena[id]) { 103 | debug_assert_eq!(parent_first_child.is_some(), parent_last_child.is_some()); 104 | parent_node.first_child = parent_first_child; 105 | parent_node.last_child = parent_last_child; 106 | } 107 | 108 | debug_assert_triangle_nodes!(arena, parent, previous, next); 109 | } 110 | 111 | /// Detaches, inserts, and updates the given node using the given neighbors. 112 | /// 113 | /// ```text 114 | /// Before: 115 | /// 116 | /// parent 117 | /// / \ 118 | /// / \ 119 | /// prev -> next 120 | /// 121 | /// After: 122 | /// 123 | /// parent 124 | /// ______/|\_____ 125 | /// / | \ 126 | /// prev -> (new) -> next 127 | /// ``` 128 | pub(crate) fn insert_with_neighbors( 129 | arena: &mut Arena, 130 | new: NodeId, 131 | parent: Option, 132 | previous_sibling: Option, 133 | next_sibling: Option, 134 | ) -> Result<(), ConsistencyError> { 135 | debug_assert_triangle_nodes!(arena, parent, previous_sibling, next_sibling); 136 | if previous_sibling == Some(new) || next_sibling == Some(new) { 137 | // One of the given neighbors is going to be detached. 138 | return Err(ConsistencyError::SiblingsLoop); 139 | } 140 | if parent == Some(new) { 141 | // The given parent is the node itself. 142 | return Err(ConsistencyError::ParentChildLoop); 143 | } 144 | 145 | SiblingsRange::new(new, new) 146 | .detach_from_siblings(arena) 147 | .transplant(arena, parent, previous_sibling, next_sibling) 148 | .expect("Should never fail: neighbors including parent are not `self`"); 149 | 150 | debug_assert_triangle_nodes!(arena, parent, previous_sibling, Some(new)); 151 | debug_assert_triangle_nodes!(arena, parent, Some(new), next_sibling); 152 | 153 | Ok(()) 154 | } 155 | 156 | /// Inserts, and updates the given detached node to the parent, after all of it's existing children 157 | /// 158 | /// ```text 159 | /// Before: 160 | /// 161 | /// parent 162 | /// / \ 163 | /// / \ 164 | /// ... -> prev_sibling 165 | /// 166 | /// After: 167 | /// 168 | /// parent 169 | /// _____/|\_____ 170 | /// / | \ 171 | /// ... -> prev -> (new) 172 | /// ``` 173 | pub(crate) fn insert_last_unchecked(arena: &mut Arena, new: NodeId, parent: NodeId) { 174 | let previous_sibling = arena[parent].last_child; 175 | DetachedSiblingsRange::new(new, new) 176 | .transplant(arena, Some(parent), previous_sibling, None) 177 | .expect( 178 | "Should never fail, callers must verify assumptions when using fast path append. 179 | `expect` only needed due to usage of shared functions that return a `Result`.", 180 | ); 181 | 182 | debug_assert_triangle_nodes!(arena, Some(parent), previous_sibling, Some(new)); 183 | } 184 | -------------------------------------------------------------------------------- /indextree/src/siblings_range.rs: -------------------------------------------------------------------------------- 1 | //! Sibling nodes range. 2 | 3 | use crate::{error::ConsistencyError, relations::connect_neighbors, Arena, NodeId}; 4 | 5 | /// Siblings range. 6 | #[derive(Debug, Clone, Copy)] 7 | pub(crate) struct SiblingsRange { 8 | /// First node. 9 | first: NodeId, 10 | /// Last node. 11 | last: NodeId, 12 | } 13 | 14 | impl SiblingsRange { 15 | /// Creates a new range. 16 | /// 17 | /// It is user's responsibility to guarantee that `first` to `last` is a 18 | /// correct range. 19 | pub(crate) fn new(first: NodeId, last: NodeId) -> Self { 20 | Self { first, last } 21 | } 22 | 23 | /// Detaches the range from the siblings out of the range, preserving 24 | /// sibling relations inside the range. 25 | pub(crate) fn detach_from_siblings(self, arena: &mut Arena) -> DetachedSiblingsRange { 26 | // Update children's parents, siblings relations outside the range, and 27 | // old parent's first and last child nodes. 28 | let parent = arena[self.first].parent; 29 | 30 | // Update siblings relations outside the range and old parent's 31 | // children if necessary. 32 | let prev_of_range = arena[self.first].previous_sibling.take(); 33 | let next_of_range = arena[self.last].next_sibling.take(); 34 | connect_neighbors(arena, parent, prev_of_range, next_of_range); 35 | 36 | if cfg!(debug_assertions) { 37 | debug_assert_eq!(arena[self.first].previous_sibling, None); 38 | debug_assert_eq!(arena[self.last].next_sibling, None); 39 | debug_assert_triangle_nodes!(arena, parent, prev_of_range, next_of_range); 40 | if let Some(parent_node) = parent.map(|id| &arena[id]) { 41 | debug_assert_eq!( 42 | parent_node.first_child.is_some(), 43 | parent_node.last_child.is_some() 44 | ); 45 | debug_assert_triangle_nodes!(arena, parent, None, parent_node.first_child); 46 | debug_assert_triangle_nodes!(arena, parent, parent_node.last_child, None); 47 | } 48 | } 49 | 50 | DetachedSiblingsRange { 51 | first: self.first, 52 | last: self.last, 53 | } 54 | } 55 | } 56 | 57 | /// Detached siblings range. 58 | /// 59 | /// Note that the nodes in the range has outdated parent information. 60 | /// It is user's responsibility to properly update them using 61 | /// `rewrite_parents()`. 62 | #[derive(Debug, Clone, Copy)] 63 | #[must_use = "This range can have outdated parent information and they should be updated"] 64 | pub(crate) struct DetachedSiblingsRange { 65 | /// First node. 66 | first: NodeId, 67 | /// Last node. 68 | last: NodeId, 69 | } 70 | 71 | impl DetachedSiblingsRange { 72 | /// Creates a new range. 73 | /// 74 | /// It is user's responsibility to guarantee that `first` to `last` is a 75 | /// correct range. 76 | pub(crate) fn new(first: NodeId, last: NodeId) -> Self { 77 | Self { first, last } 78 | } 79 | 80 | /// Rewrites the parents. 81 | /// 82 | /// # Failures 83 | /// 84 | /// Returns an error if the given parent is a node in the range. 85 | pub(crate) fn rewrite_parents( 86 | &self, 87 | arena: &mut Arena, 88 | new_parent: Option, 89 | ) -> Result<(), ConsistencyError> { 90 | // Update parents of children in the range. 91 | let mut child_opt = Some(self.first); 92 | while let Some(child) = child_opt { 93 | if Some(child) == new_parent { 94 | // Attempt to set the node itself as its parent. 95 | return Err(ConsistencyError::ParentChildLoop); 96 | } 97 | let child_node = &mut arena[child]; 98 | child_node.parent = new_parent; 99 | child_opt = child_node.next_sibling; 100 | } 101 | 102 | Ok(()) 103 | } 104 | 105 | /// Inserts the range to the given place preserving sibling relations in 106 | /// the range. 107 | /// 108 | /// This does `rewrite_parents()` automatically, so callers do not need to 109 | /// call it manually. 110 | /// 111 | /// # Failures 112 | /// 113 | /// Returns an error if the given parent is a node in the range. 114 | pub(crate) fn transplant( 115 | self, 116 | arena: &mut Arena, 117 | parent: Option, 118 | previous_sibling: Option, 119 | next_sibling: Option, 120 | ) -> Result<(), ConsistencyError> { 121 | // Check that the given arguments are consistent. 122 | if cfg!(debug_assertions) { 123 | if let Some(previous_sibling) = previous_sibling { 124 | debug_assert_eq!(arena[previous_sibling].parent, parent); 125 | } 126 | if let Some(next_sibling) = next_sibling { 127 | debug_assert_eq!(arena[next_sibling].parent, parent); 128 | } 129 | debug_assert_triangle_nodes!(arena, parent, previous_sibling, next_sibling); 130 | if let Some(parent_node) = parent.map(|id| &arena[id]) { 131 | debug_assert_eq!( 132 | parent_node.first_child.is_some(), 133 | parent_node.last_child.is_some() 134 | ); 135 | } 136 | } 137 | 138 | // Rewrite parents of the nodes in the range. 139 | self.rewrite_parents(arena, parent)?; 140 | 141 | // Connect the previous sibling and the first node in the range. 142 | connect_neighbors(arena, parent, previous_sibling, Some(self.first)); 143 | 144 | // Connect the next sibling and the last node in the range. 145 | connect_neighbors(arena, parent, Some(self.last), next_sibling); 146 | 147 | // Ensure related nodes are consistent. 148 | // Check only in debug build. 149 | if cfg!(debug_assertions) { 150 | debug_assert_triangle_nodes!(arena, parent, previous_sibling, Some(self.first)); 151 | debug_assert_triangle_nodes!(arena, parent, Some(self.last), next_sibling); 152 | if let Some(parent_node) = parent.map(|id| &arena[id]) { 153 | debug_assert!( 154 | parent_node.first_child.is_some() && parent_node.last_child.is_some(), 155 | "parent should have children (at least `self.first`)" 156 | ); 157 | debug_assert_triangle_nodes!(arena, parent, None, parent_node.first_child); 158 | debug_assert_triangle_nodes!(arena, parent, parent_node.last_child, None); 159 | } 160 | } 161 | 162 | Ok(()) 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /indextree/src/traverse.rs: -------------------------------------------------------------------------------- 1 | //! Iterators. 2 | 3 | #![allow(clippy::redundant_closure_call)] 4 | 5 | use crate::{Arena, Node, NodeId}; 6 | 7 | #[derive(Clone)] 8 | struct Iter<'a, T> { 9 | arena: &'a Arena, 10 | node: Option, 11 | } 12 | 13 | impl<'a, T> Iter<'a, T> { 14 | fn new(arena: &'a Arena, node: impl Into>) -> Self { 15 | let node = node.into(); 16 | 17 | Self { arena, node } 18 | } 19 | } 20 | 21 | #[derive(Clone)] 22 | struct DoubleEndedIter<'a, T> { 23 | arena: &'a Arena, 24 | head: Option, 25 | tail: Option, 26 | } 27 | 28 | impl<'a, T> DoubleEndedIter<'a, T> { 29 | fn new( 30 | arena: &'a Arena, 31 | head: impl Into>, 32 | tail: impl Into>, 33 | ) -> Self { 34 | let head = head.into(); 35 | let tail = tail.into(); 36 | 37 | Self { arena, head, tail } 38 | } 39 | } 40 | 41 | macro_rules! new_iterator { 42 | ($(#[$attr:meta])* $name:ident, inner = $inner:ident, new = $new:expr $(,)?) => { 43 | $(#[$attr])* 44 | #[repr(transparent)] 45 | #[derive(Clone)] 46 | pub struct $name<'a, T>($inner<'a, T>); 47 | 48 | #[allow(deprecated)] 49 | impl<'a, T> $name<'a, T> { 50 | pub(crate) fn new(arena: &'a Arena, node: NodeId) -> Self { 51 | let new: fn(&'a Arena, NodeId) -> $inner<'a, T> = $new; 52 | Self(new(arena, node)) 53 | } 54 | } 55 | }; 56 | ($(#[$attr:meta])* $name:ident, new = $new:expr, next = $next:expr $(,)?) => { 57 | new_iterator!( 58 | $(#[$attr])* 59 | $name, 60 | inner = Iter, 61 | new = $new, 62 | ); 63 | 64 | #[allow(deprecated)] 65 | impl<'a, T> Iterator for $name<'a, T> { 66 | type Item = NodeId; 67 | 68 | fn next(&mut self) -> Option { 69 | let next: fn(&Node) -> Option = $next; 70 | 71 | let node = self.0.node.take()?; 72 | self.0.node = next(&self.0.arena[node]); 73 | Some(node) 74 | } 75 | } 76 | 77 | #[allow(deprecated)] 78 | impl<'a, T> core::iter::FusedIterator for $name<'a, T> {} 79 | }; 80 | ($(#[$attr:meta])* $name:ident, new = $new:expr, next = $next:expr, next_back = $next_back:expr $(,)?) => { 81 | new_iterator!( 82 | $(#[$attr])* 83 | $name, 84 | inner = DoubleEndedIter, 85 | new = $new, 86 | ); 87 | 88 | #[allow(deprecated)] 89 | impl<'a, T> Iterator for $name<'a, T> { 90 | type Item = NodeId; 91 | 92 | fn next(&mut self) -> Option { 93 | match (self.0.head, self.0.tail) { 94 | (Some(head), Some(tail)) if head == tail => { 95 | let result = head; 96 | self.0.head = None; 97 | self.0.tail = None; 98 | Some(result) 99 | } 100 | (Some(head), None) | (Some(head), Some(_)) => { 101 | let next: fn(&Node) -> Option = $next; 102 | 103 | self.0.head = next(&self.0.arena[head]); 104 | Some(head) 105 | } 106 | (None, Some(_)) | (None, None) => None, 107 | } 108 | } 109 | } 110 | 111 | #[allow(deprecated)] 112 | impl<'a, T> ::core::iter::DoubleEndedIterator for $name<'a, T> { 113 | fn next_back(&mut self) -> Option { 114 | match (self.0.head, self.0.tail) { 115 | (Some(head), Some(tail)) if head == tail => { 116 | let result = head; 117 | self.0.head = None; 118 | self.0.tail = None; 119 | Some(result) 120 | } 121 | (None, Some(tail)) | (Some(_), Some(tail)) => { 122 | let next_back: fn(&Node) -> Option = $next_back; 123 | 124 | self.0.tail = next_back(&self.0.arena[tail]); 125 | Some(tail) 126 | } 127 | (Some(_), None)| (None, None) => None, 128 | } 129 | } 130 | } 131 | }; 132 | ($(#[$attr:meta])* $name:ident, next = $next:expr $(,)?) => { 133 | new_iterator!( 134 | $(#[$attr])* 135 | $name, 136 | new = |arena, node| Iter::new(arena, node), 137 | next = $next, 138 | ); 139 | }; 140 | ($(#[$attr:meta])* $name:ident, next = $next:expr, next_back = $next_back:expr $(,)?) => { 141 | new_iterator!( 142 | $(#[$attr])* 143 | $name, 144 | new = |arena, node| DoubleEndedIter::new(arena, node, None), 145 | next = $next, 146 | next_back = $next_back, 147 | ); 148 | }; 149 | } 150 | 151 | new_iterator!( 152 | /// An iterator of the IDs of the ancestors of a given node. 153 | Ancestors, 154 | next = |node| node.parent, 155 | ); 156 | 157 | new_iterator!( 158 | /// An iterator of the IDs of the predecessors of a given node. 159 | Predecessors, 160 | next = |node| node.previous_sibling.or(node.parent), 161 | ); 162 | 163 | new_iterator!( 164 | /// An iterator of the IDs of the siblings before a given node. 165 | PrecedingSiblings, 166 | new = |arena, node| { 167 | let first = arena 168 | .get(node) 169 | .unwrap() 170 | .parent 171 | .and_then(|parent_id| arena.get(parent_id)) 172 | .and_then(|parent| parent.first_child); 173 | 174 | DoubleEndedIter::new(arena, node, first) 175 | }, 176 | next = |head| head.previous_sibling, 177 | next_back = |tail| tail.next_sibling, 178 | ); 179 | 180 | new_iterator!( 181 | /// An iterator of the IDs of the siblings after a given node. 182 | FollowingSiblings, 183 | new = |arena, node| { 184 | let last = arena 185 | .get(node) 186 | .unwrap() 187 | .parent 188 | .and_then(|parent_id| arena.get(parent_id)) 189 | .and_then(|parent| parent.last_child); 190 | 191 | DoubleEndedIter::new(arena, node, last) 192 | }, 193 | next = |head| head.next_sibling, 194 | next_back = |tail| tail.previous_sibling, 195 | ); 196 | 197 | new_iterator!( 198 | /// An iterator of the IDs of the children of a given node, in insertion order. 199 | Children, 200 | new = |arena, node| DoubleEndedIter::new(arena, arena[node].first_child, arena[node].last_child), 201 | next = |node| node.next_sibling, 202 | next_back = |tail| tail.previous_sibling, 203 | ); 204 | 205 | new_iterator!( 206 | #[deprecated( 207 | since = "4.7.0", 208 | note = "please, use Children::rev() instead if you want to iterate in reverse" 209 | )] 210 | /// An iterator of the IDs of the children of a given node, in reverse insertion order. 211 | ReverseChildren, 212 | new = |arena, node| Iter::new(arena, arena[node].last_child), 213 | next = |node| node.previous_sibling, 214 | ); 215 | 216 | #[derive(Clone)] 217 | /// An iterator of the IDs of a given node and its descendants, as a pre-order depth-first search where children are visited in insertion order. 218 | /// 219 | /// i.e. node -> first child -> second child 220 | pub struct Descendants<'a, T>(Traverse<'a, T>); 221 | 222 | impl<'a, T> Descendants<'a, T> { 223 | pub(crate) fn new(arena: &'a Arena, current: NodeId) -> Self { 224 | Self(Traverse::new(arena, current)) 225 | } 226 | } 227 | 228 | impl Iterator for Descendants<'_, T> { 229 | type Item = NodeId; 230 | 231 | fn next(&mut self) -> Option { 232 | self.0.find_map(|edge| match edge { 233 | NodeEdge::Start(node) => Some(node), 234 | NodeEdge::End(_) => None, 235 | }) 236 | } 237 | } 238 | 239 | impl core::iter::FusedIterator for Descendants<'_, T> {} 240 | 241 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 242 | /// Indicator if the node is at a start or endpoint of the tree 243 | pub enum NodeEdge { 244 | /// Indicates that start of a node that has children. 245 | /// 246 | /// Yielded by `Traverse::next()` before the node’s descendants. In HTML or 247 | /// XML, this corresponds to an opening tag like `
`. 248 | Start(NodeId), 249 | 250 | /// Indicates that end of a node that has children. 251 | /// 252 | /// Yielded by `Traverse::next()` after the node’s descendants. In HTML or 253 | /// XML, this corresponds to a closing tag like `
` 254 | End(NodeId), 255 | } 256 | 257 | impl NodeEdge { 258 | /// Returns the next `NodeEdge` to be returned by forward depth-first traversal. 259 | /// 260 | /// # Examples 261 | /// 262 | /// ``` 263 | /// # use indextree::{Arena, NodeEdge}; 264 | /// # let mut arena = Arena::new(); 265 | /// # let n1 = arena.new_node("1"); 266 | /// # let n1_1 = arena.new_node("1_1"); 267 | /// # n1.append(n1_1, &mut arena); 268 | /// # let n1_1_1 = arena.new_node("1_1_1"); 269 | /// # n1_1.append(n1_1_1, &mut arena); 270 | /// # let n1_2 = arena.new_node("1_2"); 271 | /// # n1.append(n1_2, &mut arena); 272 | /// # let n1_3 = arena.new_node("1_3"); 273 | /// # n1.append(n1_3, &mut arena); 274 | /// # 275 | /// // arena 276 | /// // `-- 1 277 | /// // |-- 1_1 278 | /// // | `-- 1_1_1 279 | /// // |-- 1_2 280 | /// // `-- 1_3 281 | /// 282 | /// let steps = std::iter::successors( 283 | /// Some(NodeEdge::Start(n1)), 284 | /// |current| current.next_traverse(&arena) 285 | /// ) 286 | /// .collect::>(); 287 | /// let traversed_by_iter = n1.traverse(&arena).collect::>(); 288 | /// assert_eq!( 289 | /// steps, 290 | /// traversed_by_iter, 291 | /// "repeated `.next_traverse()`s emit same events as `NodeId::traverse()` iterator" 292 | /// ); 293 | /// ``` 294 | /// 295 | /// `NodeEdge` itself does not borrow an arena, so you can modify the nodes 296 | /// being traversed. 297 | /// 298 | /// ``` 299 | /// # use indextree::{Arena, NodeEdge}; 300 | /// # let mut arena = Arena::new(); 301 | /// # let n1 = arena.new_node("1".to_owned()); 302 | /// # let n1_1 = arena.new_node("1_1".to_owned()); 303 | /// # n1.append(n1_1, &mut arena); 304 | /// # let n1_1_1 = arena.new_node("1_1_1".to_owned()); 305 | /// # n1_1.append(n1_1_1, &mut arena); 306 | /// # let n1_2 = arena.new_node("1_2".to_owned()); 307 | /// # n1.append(n1_2, &mut arena); 308 | /// # let n1_3 = arena.new_node("1_3".to_owned()); 309 | /// # n1.append(n1_3, &mut arena); 310 | /// # 311 | /// // arena: Arena 312 | /// // `-- 1 313 | /// // |-- 1_1 314 | /// // | `-- 1_1_1 315 | /// // |-- 1_2 316 | /// // `-- 1_3 317 | /// 318 | /// assert_eq!(*arena[n1].get(), "1"); 319 | /// assert_eq!(*arena[n1_1_1].get(), "1_1_1"); 320 | /// assert_eq!(*arena[n1_3].get(), "1_3"); 321 | /// 322 | /// let mut next = Some(NodeEdge::Start(n1)); 323 | /// let mut count = 0; 324 | /// while let Some(current) = next { 325 | /// next = current.next_traverse(&arena); 326 | /// let current = match current { 327 | /// NodeEdge::Start(id) => id, 328 | /// NodeEdge::End(_) => continue, 329 | /// }; 330 | /// 331 | /// arena[current].get_mut().push_str(&format!(" (count={})", count)); 332 | /// count += 1; 333 | /// } 334 | /// 335 | /// assert_eq!(*arena[n1].get(), "1 (count=0)"); 336 | /// assert_eq!(*arena[n1_1_1].get(), "1_1_1 (count=2)"); 337 | /// assert_eq!(*arena[n1_3].get(), "1_3 (count=4)"); 338 | /// ``` 339 | #[must_use] 340 | pub fn next_traverse(self, arena: &Arena) -> Option { 341 | match self { 342 | NodeEdge::Start(node) => match arena[node].first_child { 343 | Some(first_child) => Some(NodeEdge::Start(first_child)), 344 | None => Some(NodeEdge::End(node)), 345 | }, 346 | NodeEdge::End(node) => { 347 | let node = &arena[node]; 348 | match node.next_sibling { 349 | Some(next_sibling) => Some(NodeEdge::Start(next_sibling)), 350 | // `node.parent()` here can only be `None` if the tree has 351 | // been modified during iteration, but silently stoping 352 | // iteration seems a more sensible behavior than panicking. 353 | None => node.parent.map(NodeEdge::End), 354 | } 355 | } 356 | } 357 | } 358 | 359 | /// Returns the previous `NodeEdge` to be returned by forward depth-first traversal. 360 | /// 361 | /// # Examples 362 | /// 363 | /// ``` 364 | /// # use indextree::{Arena, NodeEdge}; 365 | /// # let mut arena = Arena::new(); 366 | /// # let n1 = arena.new_node("1"); 367 | /// # let n1_1 = arena.new_node("1_1"); 368 | /// # n1.append(n1_1, &mut arena); 369 | /// # let n1_1_1 = arena.new_node("1_1_1"); 370 | /// # n1_1.append(n1_1_1, &mut arena); 371 | /// # let n1_2 = arena.new_node("1_2"); 372 | /// # n1.append(n1_2, &mut arena); 373 | /// # let n1_3 = arena.new_node("1_3"); 374 | /// # n1.append(n1_3, &mut arena); 375 | /// # 376 | /// // arena 377 | /// // `-- 1 378 | /// // |-- 1_1 379 | /// // | `-- 1_1_1 380 | /// // |-- 1_2 381 | /// // `-- 1_3 382 | /// 383 | /// let steps = std::iter::successors( 384 | /// Some(NodeEdge::End(n1)), 385 | /// |current| current.prev_traverse(&arena) 386 | /// ) 387 | /// .collect::>(); 388 | /// let traversed_by_iter = n1.reverse_traverse(&arena).collect::>(); 389 | /// assert_eq!( 390 | /// steps, 391 | /// traversed_by_iter, 392 | /// "repeated `.prev_traverse()`s emit same events as \ 393 | /// `NodeId::reverse_traverse()` iterator" 394 | /// ); 395 | /// ``` 396 | /// 397 | /// `NodeEdge` itself does not borrow an arena, so you can modify the nodes 398 | /// being traversed. 399 | /// 400 | /// ``` 401 | /// use indextree::{Arena, NodeEdge}; 402 | /// 403 | /// # let mut arena = Arena::new(); 404 | /// # let n1 = arena.new_node("1".to_owned()); 405 | /// # let n1_1 = arena.new_node("1_1".to_owned()); 406 | /// # n1.append(n1_1, &mut arena); 407 | /// # let n1_1_1 = arena.new_node("1_1_1".to_owned()); 408 | /// # n1_1.append(n1_1_1, &mut arena); 409 | /// # let n1_2 = arena.new_node("1_2".to_owned()); 410 | /// # n1.append(n1_2, &mut arena); 411 | /// # let n1_3 = arena.new_node("1_3".to_owned()); 412 | /// # n1.append(n1_3, &mut arena); 413 | /// # 414 | /// // arena: Arena 415 | /// // `-- 1 416 | /// // |-- 1_1 417 | /// // | `-- 1_1_1 418 | /// // |-- 1_2 419 | /// // `-- 1_3 420 | /// 421 | /// assert_eq!(*arena[n1_3].get(), "1_3"); 422 | /// assert_eq!(*arena[n1_1_1].get(), "1_1_1"); 423 | /// assert_eq!(*arena[n1].get(), "1"); 424 | /// 425 | /// let mut next = Some(NodeEdge::End(n1_3)); 426 | /// let mut count = 0; 427 | /// while let Some(current) = next { 428 | /// next = current.prev_traverse(&arena); 429 | /// let current = match current { 430 | /// NodeEdge::Start(id) => id, 431 | /// NodeEdge::End(_) => continue, 432 | /// }; 433 | /// 434 | /// arena[current].get_mut().push_str(&format!(" (count={})", count)); 435 | /// count += 1; 436 | /// } 437 | /// 438 | /// assert_eq!(*arena[n1_3].get(), "1_3 (count=0)"); 439 | /// assert_eq!(*arena[n1_1_1].get(), "1_1_1 (count=2)"); 440 | /// assert_eq!(*arena[n1].get(), "1 (count=4)"); 441 | /// ``` 442 | #[must_use] 443 | pub fn prev_traverse(self, arena: &Arena) -> Option { 444 | match self { 445 | NodeEdge::End(node) => match arena[node].last_child { 446 | Some(last_child) => Some(NodeEdge::End(last_child)), 447 | None => Some(NodeEdge::Start(node)), 448 | }, 449 | NodeEdge::Start(node) => { 450 | let node = &arena[node]; 451 | match node.previous_sibling { 452 | Some(previous_sibling) => Some(NodeEdge::End(previous_sibling)), 453 | // `node.parent()` here can only be `None` if the tree has 454 | // been modified during iteration, but silently stopping 455 | // iteration seems a more sensible behavior than panicking. 456 | None => node.parent.map(NodeEdge::Start), 457 | } 458 | } 459 | } 460 | } 461 | } 462 | 463 | #[derive(Clone)] 464 | /// An iterator of the "sides" of a node visited during a depth-first pre-order traversal, 465 | /// where node sides are visited start to end and children are visited in insertion order. 466 | /// 467 | /// i.e. node.start -> first child -> second child -> node.end 468 | pub struct Traverse<'a, T> { 469 | arena: &'a Arena, 470 | root: NodeId, 471 | next: Option, 472 | } 473 | 474 | impl<'a, T> Traverse<'a, T> { 475 | pub(crate) fn new(arena: &'a Arena, current: NodeId) -> Self { 476 | Self { 477 | arena, 478 | root: current, 479 | next: Some(NodeEdge::Start(current)), 480 | } 481 | } 482 | 483 | /// Calculates the next node. 484 | fn next_of_next(&self, next: NodeEdge) -> Option { 485 | if next == NodeEdge::End(self.root) { 486 | return None; 487 | } 488 | next.next_traverse(self.arena) 489 | } 490 | 491 | /// Returns a reference to the arena. 492 | #[inline] 493 | #[must_use] 494 | pub(crate) fn arena(&self) -> &Arena { 495 | self.arena 496 | } 497 | } 498 | 499 | impl Iterator for Traverse<'_, T> { 500 | type Item = NodeEdge; 501 | 502 | fn next(&mut self) -> Option { 503 | let next = self.next.take()?; 504 | self.next = self.next_of_next(next); 505 | Some(next) 506 | } 507 | } 508 | 509 | impl core::iter::FusedIterator for Traverse<'_, T> {} 510 | 511 | #[derive(Clone)] 512 | /// An iterator of the "sides" of a node visited during a depth-first pre-order traversal, 513 | /// where nodes are visited end to start and children are visited in reverse insertion order. 514 | /// 515 | /// i.e. node.end -> second child -> first child -> node.start 516 | pub struct ReverseTraverse<'a, T> { 517 | arena: &'a Arena, 518 | root: NodeId, 519 | next: Option, 520 | } 521 | 522 | impl<'a, T> ReverseTraverse<'a, T> { 523 | pub(crate) fn new(arena: &'a Arena, current: NodeId) -> Self { 524 | Self { 525 | arena, 526 | root: current, 527 | next: Some(NodeEdge::End(current)), 528 | } 529 | } 530 | 531 | /// Calculates the next node. 532 | fn next_of_next(&self, next: NodeEdge) -> Option { 533 | if next == NodeEdge::Start(self.root) { 534 | return None; 535 | } 536 | next.prev_traverse(self.arena) 537 | } 538 | } 539 | 540 | impl Iterator for ReverseTraverse<'_, T> { 541 | type Item = NodeEdge; 542 | 543 | fn next(&mut self) -> Option { 544 | let next = self.next.take()?; 545 | self.next = self.next_of_next(next); 546 | Some(next) 547 | } 548 | } 549 | 550 | impl core::iter::FusedIterator for ReverseTraverse<'_, T> {} 551 | -------------------------------------------------------------------------------- /indextree/tests/debug_pretty_print.rs: -------------------------------------------------------------------------------- 1 | //! Tests for debug pretty printing. 2 | 3 | use core::fmt; 4 | 5 | use indextree::{Arena, NodeId}; 6 | 7 | #[derive(Clone)] 8 | struct Label(Vec); 9 | 10 | impl fmt::Debug for Label { 11 | #[inline] 12 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 13 | // Use `Vec`'s debug formatting. 14 | self.0.fmt(f) 15 | } 16 | } 17 | 18 | impl fmt::Display for Label { 19 | // `1/2/3` for normal formatting, and `1 -> 2 -> 3` for alternate formatting. 20 | #[inline] 21 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 22 | let mut iter = self.0.iter(); 23 | match iter.next() { 24 | Some(v) => write!(f, "{}", v)?, 25 | None => return write!(f, "root"), 26 | } 27 | if f.alternate() { 28 | iter.try_for_each(|v| write!(f, " -> {}", v)) 29 | } else { 30 | iter.try_for_each(|v| write!(f, "/{}", v)) 31 | } 32 | } 33 | } 34 | 35 | macro_rules! label { 36 | ($($tt:tt)*) => { 37 | Label(vec![$($tt)*]) 38 | } 39 | } 40 | 41 | /// Returns the sample tree and the root node ID. 42 | fn sample_tree() -> (Arena