Skip to content

Commit 8a95dde

Browse files
committed
Turn Traverse into a FusedIterator by dropping the reference when returning to the root node.
1 parent 1e27c25 commit 8a95dde

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

src/iter.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl<'a, T: 'a> PartialEq for Edge<'a, T> {
243243
/// Iterator which traverses a subtree.
244244
#[derive(Debug)]
245245
pub struct Traverse<'a, T: 'a> {
246-
root: NodeRef<'a, T>,
246+
root: Option<NodeRef<'a, T>>,
247247
edge: Option<Edge<'a, T>>,
248248
}
249249
impl<'a, T: 'a> Clone for Traverse<'a, T> {
@@ -254,12 +254,15 @@ impl<'a, T: 'a> Clone for Traverse<'a, T> {
254254
}
255255
}
256256
}
257+
impl<'a, T: 'a> FusedIterator for Traverse<'a, T> {}
257258
impl<'a, T: 'a> Iterator for Traverse<'a, T> {
258259
type Item = Edge<'a, T>;
259260
fn next(&mut self) -> Option<Self::Item> {
260261
match self.edge {
261262
None => {
262-
self.edge = Some(Edge::Open(self.root));
263+
if let Some(root) = self.root {
264+
self.edge = Some(Edge::Open(root));
265+
}
263266
}
264267
Some(Edge::Open(node)) => {
265268
if let Some(first_child) = node.first_child() {
@@ -269,7 +272,8 @@ impl<'a, T: 'a> Iterator for Traverse<'a, T> {
269272
}
270273
}
271274
Some(Edge::Close(node)) => {
272-
if node == self.root {
275+
if node == self.root.unwrap() {
276+
self.root = None;
273277
self.edge = None;
274278
} else if let Some(next_sibling) = node.next_sibling() {
275279
self.edge = Some(Edge::Open(next_sibling));
@@ -290,6 +294,7 @@ impl<'a, T: 'a> Clone for Descendants<'a, T> {
290294
Descendants(self.0.clone())
291295
}
292296
}
297+
impl<'a, T: 'a> FusedIterator for Descendants<'a, T> {}
293298
impl<'a, T: 'a> Iterator for Descendants<'a, T> {
294299
type Item = NodeRef<'a, T>;
295300
fn next(&mut self) -> Option<Self::Item> {
@@ -339,7 +344,7 @@ impl<'a, T: 'a> NodeRef<'a, T> {
339344
/// Returns an iterator which traverses the subtree starting at this node.
340345
pub fn traverse(&self) -> Traverse<'a, T> {
341346
Traverse {
342-
root: *self,
347+
root: Some(*self),
343348
edge: None,
344349
}
345350
}

tests/iter.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,16 @@ fn traverse() {
203203
);
204204
}
205205

206+
#[test]
207+
fn traverse_fused() {
208+
let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
209+
210+
let mut traversal = tree.root().traverse();
211+
212+
assert_eq!(traversal.by_ref().count(), 2 * 5);
213+
assert_eq!(traversal.next(), None);
214+
}
215+
206216
#[test]
207217
fn descendants() {
208218
let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
@@ -215,3 +225,13 @@ fn descendants() {
215225

216226
assert_eq!(&[&'a', &'b', &'d', &'e', &'c',], &descendants[..]);
217227
}
228+
229+
#[test]
230+
fn descendants_fused() {
231+
let tree = tree!('a' => { 'b' => { 'd', 'e' }, 'c' });
232+
233+
let mut descendants = tree.root().descendants();
234+
235+
assert_eq!(descendants.by_ref().count(), 5);
236+
assert_eq!(descendants.next(), None);
237+
}

0 commit comments

Comments
 (0)