arena_tree/
lib.rs

1/*! 
2A DOM-like tree data structure based on `&Node` references.
3
4Any non-trivial tree involves reference cycles
5(e.g. if a node has a first child, the parent of the child is that node).
6To enable this, nodes need to live in an arena allocator
7such as `arena::TypedArena` distrubuted with rustc (which is `#[unstable]` as of this writing)
8or [`typed_arena::Arena`](https://crates.io/crates/typed-arena).
9
10If you need mutability in the node’s `data`,
11make it a cell (`Cell` or `RefCell`) or use cells inside of it.
12
13## Example
14
15```rust
16extern crate typed_arena;
17extern crate arena_tree;
18use std::cell::RefCell;
19
20let arena = typed_arena::Arena::new();
21let a = arena.alloc(arena_tree::Node::new(RefCell::new(String::new())));
22let b = arena.alloc(arena_tree::Node::new(RefCell::new(String::new())));
23a.append(b);
24b.data.borrow_mut().push_str("content");
25assert_eq!(a.descendants().map(|node| node.data.borrow().clone()).collect::<Vec<_>>(), [
26    "".to_string(), "content".to_string()
27]);
28```
29
30*/
31
32use std::cell::Cell;
33
34
35/// A node inside a DOM-like tree.
36pub struct Node<'a, T: 'a> {
37    parent: Cell<Option<&'a Node<'a, T>>>,
38    previous_sibling: Cell<Option<&'a Node<'a, T>>>,
39    next_sibling: Cell<Option<&'a Node<'a, T>>>,
40    first_child: Cell<Option<&'a Node<'a, T>>>,
41    last_child: Cell<Option<&'a Node<'a, T>>>,
42    pub data: T,
43}
44
45
46fn same_ref<T>(a: &T, b: &T) -> bool {
47    a as *const T == b as *const T
48}
49
50trait Take<T> {
51    fn take(&self) -> Option<T>;
52}
53
54impl<T: Copy> Take<T> for Cell<Option<T>> {
55    fn take(&self) -> Option<T> {
56        let value = self.get();
57        self.set(None);
58        value
59    }
60}
61
62impl<'a, T> Node<'a, T> {
63    /// Create a new node from its associated data.
64    ///
65    /// Typically, this node needs to be moved into an arena allocator
66    /// before it can be used in a tree.
67    pub fn new(data: T) -> Node<'a, T> {
68        Node {
69            parent: Cell::new(None),
70            first_child: Cell::new(None),
71            last_child: Cell::new(None),
72            previous_sibling: Cell::new(None),
73            next_sibling: Cell::new(None),
74            data: data,
75        }
76    }
77
78    /// Return a reference to the parent node, unless this node is the root of the tree.
79    pub fn parent(&self) -> Option<&'a Node<'a, T>> {
80        self.parent.get()
81    }
82
83    /// Return a reference to the first child of this node, unless it has no child.
84    pub fn first_child(&self) -> Option<&'a Node<'a, T>> {
85        self.first_child.get()
86    }
87
88    /// Return a reference to the last child of this node, unless it has no child.
89    pub fn last_child(&self) -> Option<&'a Node<'a, T>> {
90        self.last_child.get()
91    }
92
93    /// Return a reference to the previous sibling of this node, unless it is a first child.
94    pub fn previous_sibling(&self) -> Option<&'a Node<'a, T>> {
95        self.previous_sibling.get()
96    }
97
98    /// Return a reference to the previous sibling of this node, unless it is a last child.
99    pub fn next_sibling(&self) -> Option<&'a Node<'a, T>> {
100        self.next_sibling.get()
101    }
102
103    /// Returns whether two references point to the same node.
104    pub fn same_node(&self, other: &Node<'a, T>) -> bool {
105        same_ref(self, other)
106    }
107
108    /// Return an iterator of references to this node and its ancestors.
109    ///
110    /// Call `.next().unwrap()` once on the iterator to skip the node itself.
111    pub fn ancestors(&'a self) -> Ancestors<'a, T> {
112        Ancestors(Some(self))
113    }
114
115    /// Return an iterator of references to this node and the siblings before it.
116    ///
117    /// Call `.next().unwrap()` once on the iterator to skip the node itself.
118    pub fn preceding_siblings(&'a self) -> PrecedingSiblings<'a, T> {
119        PrecedingSiblings(Some(self))
120    }
121
122    /// Return an iterator of references to this node and the siblings after it.
123    ///
124    /// Call `.next().unwrap()` once on the iterator to skip the node itself.
125    pub fn following_siblings(&'a self) -> FollowingSiblings<'a, T> {
126        FollowingSiblings(Some(self))
127    }
128
129    /// Return an iterator of references to this node’s children.
130    pub fn children(&'a self) -> Children<'a, T> {
131        Children(self.first_child.get())
132    }
133
134    /// Return an iterator of references to this node’s children, in reverse order.
135    pub fn reverse_children(&'a self) -> ReverseChildren<'a, T> {
136        ReverseChildren(self.last_child.get())
137    }
138
139    /// Return an iterator of references to this node and its descendants, in tree order.
140    ///
141    /// Parent nodes appear before the descendants.
142    /// Call `.next().unwrap()` once on the iterator to skip the node itself.
143    pub fn descendants(&'a self) -> Descendants<'a, T> {
144        Descendants(self.traverse())
145    }
146
147    /// Return an iterator of references to this node and its descendants, in tree order.
148    pub fn traverse(&'a self) -> Traverse<'a, T> {
149        Traverse {
150            root: self,
151            next: Some(NodeEdge::Start(self)),
152        }
153    }
154
155    /// Return an iterator of references to this node and its descendants, in tree order.
156    pub fn reverse_traverse(&'a self) -> ReverseTraverse<'a, T> {
157        ReverseTraverse {
158            root: self,
159            next: Some(NodeEdge::End(self)),
160        }
161    }
162
163    /// Detach a node from its parent and siblings. Children are not affected.
164    pub fn detach(&self) {
165        let parent = self.parent.take();
166        let previous_sibling = self.previous_sibling.take();
167        let next_sibling = self.next_sibling.take();
168
169        if let Some(next_sibling) = next_sibling {
170            next_sibling.previous_sibling.set(previous_sibling);
171        } else if let Some(parent) = parent {
172            parent.last_child.set(previous_sibling);
173        }
174
175        if let Some(previous_sibling) = previous_sibling {
176            previous_sibling.next_sibling.set(next_sibling);
177        } else if let Some(parent) = parent {
178            parent.first_child.set(next_sibling);
179        }
180    }
181
182    /// Append a new child to this node, after existing children.
183    pub fn append(&'a self, new_child: &'a Node<'a, T>) {
184        new_child.detach();
185        new_child.parent.set(Some(self));
186        if let Some(last_child) = self.last_child.take() {
187            new_child.previous_sibling.set(Some(last_child));
188            debug_assert!(last_child.next_sibling.get().is_none());
189            last_child.next_sibling.set(Some(new_child));
190        } else {
191            debug_assert!(self.first_child.get().is_none());
192            self.first_child.set(Some(new_child));
193        }
194        self.last_child.set(Some(new_child));
195    }
196
197    /// Prepend a new child to this node, before existing children.
198    pub fn prepend(&'a self, new_child: &'a Node<'a, T>) {
199        new_child.detach();
200        new_child.parent.set(Some(self));
201        if let Some(first_child) = self.first_child.take() {
202            debug_assert!(first_child.previous_sibling.get().is_none());
203            first_child.previous_sibling.set(Some(new_child));
204            new_child.next_sibling.set(Some(first_child));
205        } else {
206            debug_assert!(self.first_child.get().is_none());
207            self.last_child.set(Some(new_child));
208        }
209        self.first_child.set(Some(new_child));
210    }
211
212    /// Insert a new sibling after this node.
213    pub fn insert_after(&'a self, new_sibling: &'a Node<'a, T>) {
214        new_sibling.detach();
215        new_sibling.parent.set(self.parent.get());
216        new_sibling.previous_sibling.set(Some(self));
217        if let Some(next_sibling) = self.next_sibling.take() {
218            debug_assert!(same_ref(next_sibling.previous_sibling.get().unwrap(), self));
219            next_sibling.previous_sibling.set(Some(new_sibling));
220            new_sibling.next_sibling.set(Some(next_sibling));
221        } else if let Some(parent) = self.parent.get() {
222            debug_assert!(same_ref(parent.last_child.get().unwrap(), self));
223            parent.last_child.set(Some(new_sibling));
224        }
225        self.next_sibling.set(Some(new_sibling));
226    }
227
228    /// Insert a new sibling before this node.
229    pub fn insert_before(&'a self, new_sibling: &'a Node<'a, T>) {
230        new_sibling.detach();
231        new_sibling.parent.set(self.parent.get());
232        new_sibling.next_sibling.set(Some(self));
233        if let Some(previous_sibling) = self.previous_sibling.take() {
234            new_sibling.previous_sibling.set(Some(previous_sibling));
235            debug_assert!(same_ref(previous_sibling.next_sibling.get().unwrap(), self));
236            previous_sibling.next_sibling.set(Some(new_sibling));
237        } else if let Some(parent) = self.parent.get() {
238            debug_assert!(same_ref(parent.first_child.get().unwrap(), self));
239            parent.first_child.set(Some(new_sibling));
240        }
241        self.previous_sibling.set(Some(new_sibling));
242    }
243}
244
245
246macro_rules! axis_iterator {
247    (#[$attr:meta] $name: ident: $next: ident) => {
248        #[$attr]
249        pub struct $name<'a, T: 'a>(Option<&'a Node<'a, T>>);
250
251        impl<'a, T> Iterator for $name<'a, T> {
252            type Item = &'a Node<'a, T>;
253
254            fn next(&mut self) -> Option<&'a Node<'a, T>> {
255                match self.0.take() {
256                    Some(node) => {
257                        self.0 = node.$next.get();
258                        Some(node)
259                    }
260                    None => None
261                }
262            }
263        }
264    }
265}
266
267axis_iterator! {
268    #[doc = "An iterator of references to the ancestors a given node."]
269    Ancestors: parent
270}
271
272axis_iterator! {
273    #[doc = "An iterator of references to the siblings before a given node."]
274    PrecedingSiblings: previous_sibling
275}
276
277axis_iterator! {
278    #[doc = "An iterator of references to the siblings after a given node."]
279    FollowingSiblings: next_sibling
280}
281
282axis_iterator! {
283    #[doc = "An iterator of references to the children of a given node."]
284    Children: next_sibling
285}
286
287axis_iterator! {
288    #[doc = "An iterator of references to the children of a given node, in reverse order."]
289    ReverseChildren: previous_sibling
290}
291
292
293/// An iterator of references to a given node and its descendants, in tree order.
294pub struct Descendants<'a, T: 'a>(Traverse<'a, T>);
295
296impl<'a, T> Iterator for Descendants<'a, T> {
297    type Item = &'a Node<'a, T>;
298
299    fn next(&mut self) -> Option<&'a Node<'a, T>> {
300        loop {
301            match self.0.next() {
302                Some(NodeEdge::Start(node)) => return Some(node),
303                Some(NodeEdge::End(_)) => {}
304                None => return None
305            }
306        }
307    }
308}
309
310
311#[derive(Debug, Clone)]
312pub enum NodeEdge<T> {
313    /// Indicates that start of a node that has children.
314    /// Yielded by `Traverse::next` before the node’s descendants.
315    /// In HTML or XML, this corresponds to an opening tag like `<div>`
316    Start(T),
317
318    /// Indicates that end of a node that has children.
319    /// Yielded by `Traverse::next` after the node’s descendants.
320    /// In HTML or XML, this corresponds to a closing tag like `</div>`
321    End(T),
322}
323
324macro_rules! traverse_iterator {
325    (#[$attr:meta] $name: ident: $first_child: ident, $next_sibling: ident) => {
326        #[$attr]
327        pub struct $name<'a, T: 'a> {
328            root: &'a Node<'a, T>,
329            next: Option<NodeEdge<&'a Node<'a, T>>>,
330        }
331
332        impl<'a, T> Iterator for $name<'a, T> {
333            type Item = NodeEdge<&'a Node<'a, T>>;
334
335            fn next(&mut self) -> Option<NodeEdge<&'a Node<'a, T>>> {
336                match self.next.take() {
337                    Some(item) => {
338                        self.next = match item {
339                            NodeEdge::Start(node) => {
340                                match node.$first_child.get() {
341                                    Some(child) => Some(NodeEdge::Start(child)),
342                                    None => Some(NodeEdge::End(node))
343                                }
344                            }
345                            NodeEdge::End(node) => {
346                                if node.same_node(self.root) {
347                                    None
348                                } else {
349                                    match node.$next_sibling.get() {
350                                        Some(sibling) => Some(NodeEdge::Start(sibling)),
351                                        None => match node.parent.get() {
352                                            Some(parent) => Some(NodeEdge::End(parent)),
353
354                                            // `node.parent()` here can only be `None`
355                                            // if the tree has been modified during iteration,
356                                            // but silently stoping iteration
357                                            // seems a more sensible behavior than panicking.
358                                            None => None
359                                        }
360                                    }
361                                }
362                            }
363                        };
364                        Some(item)
365                    }
366                    None => None
367                }
368            }
369        }
370    }
371}
372
373traverse_iterator! {
374    #[doc = "An iterator of the start and end edges of a given node and its descendants, in tree order."]
375    Traverse: first_child, next_sibling
376}
377
378traverse_iterator! {
379    #[doc = "An iterator of the start and end edges of a given node and its descendants, in reverse tree order."]
380    ReverseTraverse: last_child, previous_sibling
381}
382
383
384#[cfg(test)]
385extern crate typed_arena;
386
387#[test]
388fn it_works() {
389    struct DropTracker<'a>(&'a Cell<u32>);
390    impl<'a> Drop for DropTracker<'a> {
391        fn drop(&mut self) {
392            self.0.set(self.0.get() + 1);
393        }
394    }
395
396    let drop_counter = Cell::new(0);
397    {
398        let mut new_counter = 0;
399        let arena = typed_arena::Arena::new();
400        let mut new = || {
401            new_counter += 1;
402            arena.alloc(Node::new((new_counter, DropTracker(&drop_counter))))
403        };
404
405        let a = new();  // 1
406        a.append(new());  // 2
407        a.append(new());  // 3
408        a.prepend(new());  // 4
409        let b = new();  // 5
410        b.append(a);
411        a.insert_before(new());  // 6
412        a.insert_before(new());  // 7
413        a.insert_after(new());  // 8
414        a.insert_after(new());  // 9
415        let c = new();  // 10
416        b.append(c);
417
418        assert_eq!(drop_counter.get(), 0);
419        c.previous_sibling.get().unwrap().detach();
420        assert_eq!(drop_counter.get(), 0);
421
422        assert_eq!(b.descendants().map(|node| node.data.0).collect::<Vec<_>>(), [
423            5, 6, 7, 1, 4, 2, 3, 9, 10
424        ]);
425    }
426
427    assert_eq!(drop_counter.get(), 10);
428}