]>
git.proxmox.com Git - rustc.git/blob - vendor/pulldown-cmark/src/tree.rs
1 // Copyright 2018 Google LLC
3 // Use of this source code is governed by an MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT.
7 //! A Vec-based container for a tree structure.
9 use std
::num
::NonZeroUsize
;
10 use std
::ops
::{Add, Sub}
;
12 #[derive(Debug, Eq, PartialEq, Copy, Clone, PartialOrd)]
13 pub struct TreeIndex(NonZeroUsize
);
16 fn new(i
: usize) -> Self {
17 TreeIndex(NonZeroUsize
::new(i
).unwrap())
20 pub fn get(self) -> usize {
25 impl Add
<usize> for TreeIndex
{
26 type Output
= TreeIndex
;
28 fn add(self, rhs
: usize) -> Self {
29 let inner
= self.0.get() + rhs
;
34 impl Sub
<usize> for TreeIndex
{
35 type Output
= TreeIndex
;
37 fn sub(self, rhs
: usize) -> Self {
38 let inner
= self.0.get().checked_sub(rhs
).unwrap();
43 #[derive(Debug, Clone, Copy)]
45 pub child
: Option
<TreeIndex
>,
46 pub next
: Option
<TreeIndex
>,
50 /// A tree abstraction, intended for fast building as a preorder traversal.
54 spine
: Vec
<TreeIndex
>, // indices of nodes on path to current node
55 cur
: Option
<TreeIndex
>,
58 impl<T
: Default
> Tree
<T
> {
59 // Indices start at one, so we place a dummy value at index zero.
60 // The alternative would be subtracting one from every TreeIndex
61 // every time we convert it to usize to index our nodes.
62 pub fn with_capacity(cap
: usize) -> Tree
<T
> {
63 let mut nodes
= Vec
::with_capacity(cap
);
67 item
: <T
as Default
>::default(),
76 /// Returns the index of the element currently in focus.
77 pub fn cur(&self) -> Option
<TreeIndex
> {
81 /// Append one item to the current position in the tree.
82 pub fn append(&mut self, item
: T
) -> TreeIndex
{
83 let ix
= self.create_node(item
);
86 if let Some(ix
) = self.cur
{
88 } else if let Some(&parent
) = self.spine
.last() {
89 self[parent
].child
= this
;
95 /// Create an isolated node.
96 pub fn create_node(&mut self, item
: T
) -> TreeIndex
{
97 let this
= self.nodes
.len();
98 self.nodes
.push(Node
{
106 /// Push down one level, so that new items become children of the current node.
107 /// The new focus index is returned.
108 pub fn push(&mut self) -> TreeIndex
{
109 let cur_ix
= self.cur
.unwrap();
110 self.spine
.push(cur_ix
);
111 self.cur
= self[cur_ix
].child
;
115 /// Pop back up a level.
116 pub fn pop(&mut self) -> Option
<TreeIndex
> {
117 let ix
= Some(self.spine
.pop()?
);
122 /// Look at the parent node.
123 pub fn peek_up(&self) -> Option
<TreeIndex
> {
124 self.spine
.last().copied()
127 /// Look at grandparent node.
128 pub fn peek_grandparent(&self) -> Option
<TreeIndex
> {
129 if self.spine
.len() >= 2 {
130 Some(self.spine
[self.spine
.len() - 2])
136 /// Returns true when there are no nodes in the tree, false otherwise.
137 pub fn is_empty(&self) -> bool
{
138 self.nodes
.len() <= 1
141 /// Returns the length of the spine.
142 pub fn spine_len(&self) -> usize {
146 /// Resets the focus to the first node added to the tree, if it exists.
147 pub fn reset(&mut self) {
148 self.cur
= if self.is_empty() {
151 Some(TreeIndex
::new(1))
156 /// Walks the spine from a root node up to, but not including, the current node.
157 pub fn walk_spine(&self) -> impl std
::iter
::DoubleEndedIterator
<Item
= &TreeIndex
> {
161 /// Moves focus to the next sibling of the given node.
162 pub fn next_sibling(&mut self, cur_ix
: TreeIndex
) -> Option
<TreeIndex
> {
163 self.cur
= self[cur_ix
].next
;
168 impl<T
> std
::fmt
::Debug
for Tree
<T
>
172 fn fmt(&self, f
: &mut std
::fmt
::Formatter
) -> std
::fmt
::Result
{
177 f
: &mut std
::fmt
::Formatter
,
178 ) -> std
::fmt
::Result
185 writeln
!(f
, "{:?}", &tree
[cur
].item
)?
;
186 if let Some(child_ix
) = tree
[cur
].child
{
187 debug_tree(tree
, child_ix
, indent
+ 1, f
)?
;
189 if let Some(next_ix
) = tree
[cur
].next
{
190 debug_tree(tree
, next_ix
, indent
, f
)?
;
195 if self.nodes
.len() > 1 {
196 let cur
= TreeIndex(NonZeroUsize
::new(1).unwrap());
197 debug_tree(self, cur
, 0, f
)
199 write
!(f
, "Empty tree")
204 impl<T
> std
::ops
::Index
<TreeIndex
> for Tree
<T
> {
205 type Output
= Node
<T
>;
207 fn index(&self, ix
: TreeIndex
) -> &Self::Output
{
208 self.nodes
.index(ix
.get())
212 impl<T
> std
::ops
::IndexMut
<TreeIndex
> for Tree
<T
> {
213 fn index_mut(&mut self, ix
: TreeIndex
) -> &mut Node
<T
> {
214 self.nodes
.index_mut(ix
.get())