syntree/node/walk.rs
1use core::fmt;
2use core::iter::FusedIterator;
3
4use crate::flavor::Flavor;
5use crate::links::Links;
6use crate::node::Node;
7use crate::node::{Event, SkipTokens, WalkEvents};
8
9/// An iterator that walks over the entire tree, visiting every node exactly
10/// once.
11///
12/// See [`Tree::walk`][crate::Tree::walk] or [`Node::walk`].
13///
14/// # Examples
15///
16/// ```
17/// let tree = syntree::tree! {
18/// "root" => {
19/// "c1" => {
20/// "c2" => {},
21/// "c3" => {},
22/// "c4" => {},
23/// },
24/// "c5" => {},
25/// "c6" => {
26/// "c7" => {},
27/// }
28/// }
29/// };
30///
31/// // Walk the entire tree.
32/// assert_eq!(
33/// tree.walk().map(|n| n.value()).collect::<Vec<_>>(),
34/// ["root", "c1", "c2", "c3", "c4", "c5", "c6", "c7"],
35/// );
36///
37/// // Walk from the root.
38/// let root = tree.first().ok_or("missing root node")?;
39///
40/// assert_eq!(
41/// root.walk().map(|n| n.value()).collect::<Vec<_>>(),
42/// ["root", "c1", "c2", "c3", "c4", "c5", "c6", "c7"],
43/// );
44///
45/// // Walk from c1 and visit siblings.
46/// let c1 = root.first().ok_or("missing c1 node")?;
47///
48/// assert_eq!(
49/// c1.walk().map(|n| n.value()).collect::<Vec<_>>(),
50/// ["c1", "c2", "c3", "c4", "c5", "c6", "c7"],
51/// );
52///
53/// assert_eq!(
54/// c1.walk_from().map(|n| n.value()).collect::<Vec<_>>(),
55/// ["c5", "c6", "c7"],
56/// );
57///
58/// // Walk from c4 and visit parent siblings.
59/// let c4 = c1.last().ok_or("missing c1 node")?;
60///
61/// assert_eq!(
62/// c4.walk().map(|n| n.value()).collect::<Vec<_>>(),
63/// ["c4", "c5", "c6", "c7"],
64/// );
65///
66/// assert_eq!(
67/// c4.walk_from().map(|n| n.value()).collect::<Vec<_>>(),
68/// ["c5", "c6", "c7"],
69/// );
70///
71/// // Walk from c5 and visit siblings.
72/// let c5 = c1.next().ok_or("missing c5 node")?;
73///
74/// assert_eq!(
75/// c5.walk().map(|n| n.value()).collect::<Vec<_>>(),
76/// ["c5", "c6", "c7"],
77/// );
78///
79/// assert_eq!(
80/// c5.walk_from().map(|n| n.value()).collect::<Vec<_>>(),
81/// ["c6", "c7"],
82/// );
83/// # Ok::<_, Box<dyn core::error::Error>>(())
84/// ```
85pub struct Walk<'a, T, F>
86where
87 T: Copy,
88 F: Flavor,
89{
90 iter: WalkEvents<'a, T, F>,
91 // A tree-level walk has no single node to stay inside, so `inside` must
92 // not stop when the walk climbs back to the top level.
93 bounded: bool,
94}
95
96impl<'a, T, F> Walk<'a, T, F>
97where
98 T: Copy,
99 F: Flavor,
100{
101 /// Construct a new walk starting at a node.
102 #[inline]
103 pub(crate) fn new(
104 tree: &'a [Links<T, F::Index, F::Pointer>],
105 node: Option<F::Pointer>,
106 e: Event,
107 ) -> Self {
108 Self {
109 iter: WalkEvents::new(tree, node, e),
110 bounded: true,
111 }
112 }
113
114 /// Construct a new walk over every root of a tree.
115 #[inline]
116 pub(crate) fn tree(
117 tree: &'a [Links<T, F::Index, F::Pointer>],
118 node: Option<F::Pointer>,
119 ) -> Self {
120 Self {
121 iter: WalkEvents::new(tree, node, Event::Next),
122 bounded: false,
123 }
124 }
125
126 /// Convert this iterator into one that limits the walk to inside the
127 /// node it started at, visiting every node exactly once.
128 ///
129 /// The scope is the node the walk was constructed from, such as through
130 /// [`Node::walk`] or [`Node::walk_from`], even if this iterator has already
131 /// been advanced. A walk constructed through
132 /// [`Tree::walk`][crate::Tree::walk] has the whole tree as its scope, so it
133 /// visits the remaining nodes under every root.
134 ///
135 /// # Examples
136 ///
137 /// ```
138 /// let tree = syntree::tree! {
139 /// "n1" => {
140 /// "n3" => {
141 /// "n4" => {},
142 /// "n5" => {},
143 /// }
144 /// },
145 /// "n6" => {
146 /// "n7"
147 /// }
148 /// };
149 ///
150 /// let values = tree.walk().map(|n| n.value()).collect::<Vec<_>>();
151 /// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
152 ///
153 /// let n1 = tree.first().ok_or("missing n1")?;
154 ///
155 /// let values = n1.walk().map(|n| n.value()).collect::<Vec<_>>();
156 /// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
157 ///
158 /// let values = n1.walk().inside().map(|n| n.value()).collect::<Vec<_>>();
159 /// assert_eq!(values, ["n1", "n3", "n4", "n5"]);
160 ///
161 /// let values = n1.walk_from().inside().map(|n| n.value()).collect::<Vec<_>>();
162 /// let empty: [&str; 0] = [];
163 /// assert_eq!(values, empty);
164 ///
165 /// let values = tree.walk().inside().map(|n| n.value()).collect::<Vec<_>>();
166 /// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
167 ///
168 /// let mut walk = n1.walk();
169 /// assert_eq!(walk.next().map(|n| n.value()), Some("n1"));
170 /// assert_eq!(walk.next().map(|n| n.value()), Some("n3"));
171 /// let values = walk.inside().map(|n| n.value()).collect::<Vec<_>>();
172 /// assert_eq!(values, ["n4", "n5"]);
173 ///
174 /// # Ok::<_, Box<dyn core::error::Error>>(())
175 /// ```
176 #[inline]
177 #[must_use]
178 pub fn inside(self) -> Inside<'a, T, F> {
179 Inside {
180 iter: self.iter,
181 bounded: self.bounded,
182 }
183 }
184
185 /// Convert this iterator into one which includes depths.
186 ///
187 /// See [`WithDepths`] for how depths are counted.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// let tree = syntree::tree! {
193 /// "root" => {
194 /// "c1" => {
195 /// "c2" => {},
196 /// "c3" => {},
197 /// }
198 /// }
199 /// };
200 ///
201 /// let mut it = tree.walk().with_depths().map(|(d, n)| (d, n.value()));
202 /// assert!(it.eq([(0, "root"), (1, "c1"), (2, "c2"), (2, "c3")]));
203 ///
204 /// # Ok::<_, Box<dyn core::error::Error>>(())
205 /// ```
206 #[inline]
207 #[must_use]
208 pub fn with_depths(self) -> WithDepths<'a, T, F> {
209 WithDepths { iter: self.iter }
210 }
211
212 /// Construct a [`SkipTokens`] iterator from the remainder of this iterator.
213 /// This filters out childless nodes, also known as tokens.
214 ///
215 /// See [`SkipTokens`] for documentation.
216 #[inline]
217 #[must_use]
218 pub fn skip_tokens(self) -> SkipTokens<Self> {
219 SkipTokens::new(self)
220 }
221
222 /// Get the next node with a corresponding depth.
223 ///
224 /// Depths are relative to the node the walk started at and become negative
225 /// once a walk started from a [`Node`] leaves that node's subtree, see
226 /// [`WithDepths`].
227 ///
228 /// Alternatively you can use [`WithDepths`] through [`Walk::with_depths`].
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// use std::iter;
234 ///
235 /// let tree = syntree::tree! {
236 /// "root" => {
237 /// "c1" => {
238 /// "c2" => {},
239 /// "c3" => {},
240 /// }
241 /// }
242 /// };
243 ///
244 /// let mut it = tree.walk();
245 /// let it = iter::from_fn(move || it.next_with_depth());
246 /// let it = it.map(|(d, n)| (d, n.value()));
247 ///
248 /// assert!(it.eq([(0, "root"), (1, "c1"), (2, "c2"), (2, "c3")]));
249 ///
250 /// # Ok::<_, Box<dyn core::error::Error>>(())
251 /// ```
252 #[inline]
253 #[must_use]
254 pub fn next_with_depth(&mut self) -> Option<(isize, Node<'a, T, F>)> {
255 next_with_depth(&mut self.iter)
256 }
257}
258
259impl<T, F> Clone for Walk<'_, T, F>
260where
261 T: Copy,
262 F: Flavor,
263{
264 #[inline]
265 fn clone(&self) -> Self {
266 Self {
267 iter: self.iter.clone(),
268 bounded: self.bounded,
269 }
270 }
271}
272
273impl<T, F> Default for Walk<'_, T, F>
274where
275 T: Copy,
276 F: Flavor,
277{
278 #[inline]
279 fn default() -> Self {
280 Self {
281 iter: WalkEvents::default(),
282 bounded: true,
283 }
284 }
285}
286
287impl<'a, T, F> Iterator for Walk<'a, T, F>
288where
289 T: Copy,
290 F: Flavor,
291{
292 type Item = Node<'a, T, F>;
293
294 #[inline]
295 fn next(&mut self) -> Option<Self::Item> {
296 loop {
297 let (event, node) = self.iter.next()?;
298
299 if !matches!(event, Event::Up) {
300 return Some(node);
301 }
302 }
303 }
304}
305
306impl<T, F> FusedIterator for Walk<'_, T, F>
307where
308 T: Copy,
309 F: Flavor,
310{
311}
312
313/// An iterator that walks over the entire tree, visiting every node exactly
314/// once and yielding each node together with its depth. This is constructed
315/// with [`Walk::with_depths`].
316///
317/// Depths are relative to the node the walk started at, which has depth `0`.
318/// A walk started from a [`Node`] continues past the end of that node's
319/// subtree into the following siblings of its ancestors, and those nodes have
320/// negative depths. This is why depths are [`isize`]. A walk started through
321/// [`Tree::walk`][crate::Tree::walk] gives every root depth `0`.
322///
323/// # Examples
324///
325/// ```
326/// let tree = syntree::tree! {
327/// "root" => {
328/// "c1" => {
329/// "c2" => {},
330/// "c3" => {},
331/// "c4" => {},
332/// },
333/// "c5" => {},
334/// "c6" => {}
335/// }
336/// };
337///
338/// assert_eq!(
339/// tree.walk().with_depths().map(|(d, n)| (d, n.value())).collect::<Vec<_>>(),
340/// [
341/// (0, "root"),
342/// (1, "c1"),
343/// (2, "c2"),
344/// (2, "c3"),
345/// (2, "c4"),
346/// (1, "c5"),
347/// (1, "c6")
348/// ]
349/// );
350///
351/// let root = tree.first().ok_or("missing root node")?;
352///
353/// assert_eq!(
354/// root.walk().with_depths().map(|(d, n)| (d, n.value())).collect::<Vec<_>>(),
355/// [
356/// (0, "root"),
357/// (1, "c1"),
358/// (2, "c2"),
359/// (2, "c3"),
360/// (2, "c4"),
361/// (1, "c5"),
362/// (1, "c6")
363/// ]
364/// );
365/// # Ok::<_, Box<dyn core::error::Error>>(())
366/// ```
367///
368/// Leaving the subtree of the starting node gives negative depths:
369///
370/// ```
371/// let tree = syntree::tree! {
372/// "root" => {
373/// "b" => {
374/// "b1" => {}
375/// },
376/// "c" => {},
377/// "d" => {}
378/// },
379/// "root2" => {
380/// "e" => {}
381/// }
382/// };
383///
384/// let b1 = tree.walk().find(|n| n.value() == "b1").ok_or("missing b1")?;
385///
386/// assert_eq!(
387/// b1.walk().with_depths().map(|(d, n)| (d, n.value())).collect::<Vec<_>>(),
388/// [(0, "b1"), (-1, "c"), (-1, "d"), (-2, "root2"), (-1, "e")]
389/// );
390///
391/// assert_eq!(
392/// tree.walk().with_depths().map(|(d, n)| (d, n.value())).collect::<Vec<_>>(),
393/// [(0, "root"), (1, "b"), (2, "b1"), (1, "c"), (1, "d"), (0, "root2"), (1, "e")]
394/// );
395/// # Ok::<_, Box<dyn core::error::Error>>(())
396/// ```
397pub struct WithDepths<'a, T, F>
398where
399 T: Copy,
400 F: Flavor,
401{
402 iter: WalkEvents<'a, T, F>,
403}
404
405impl<'a, T, F> Iterator for WithDepths<'a, T, F>
406where
407 T: Copy,
408 F: Flavor,
409{
410 type Item = (isize, Node<'a, T, F>);
411
412 #[inline]
413 fn next(&mut self) -> Option<Self::Item> {
414 next_with_depth(&mut self.iter)
415 }
416}
417
418#[inline]
419fn next_with_depth<'a, T, F>(iter: &mut WalkEvents<'a, T, F>) -> Option<(isize, Node<'a, T, F>)>
420where
421 T: Copy,
422 F: Flavor,
423{
424 loop {
425 let depth = iter.depth();
426 let (event, node) = iter.next()?;
427
428 if !matches!(event, Event::Up) {
429 return Some((depth, node));
430 }
431 }
432}
433
434impl<T, F> FusedIterator for WithDepths<'_, T, F>
435where
436 T: Copy,
437 F: Flavor,
438{
439}
440
441impl<T, F> Clone for WithDepths<'_, T, F>
442where
443 T: Copy,
444 F: Flavor,
445{
446 #[inline]
447 fn clone(&self) -> Self {
448 Self {
449 iter: self.iter.clone(),
450 }
451 }
452}
453
454impl<T, F> Default for WithDepths<'_, T, F>
455where
456 T: Copy,
457 F: Flavor,
458{
459 #[inline]
460 fn default() -> Self {
461 Self {
462 iter: WalkEvents::default(),
463 }
464 }
465}
466
467/// An iterator that limits the walk to inside the node it started at, visiting
468/// every node exactly once. This is constructed with [`Walk::inside`].
469///
470/// The scope is the node the [`Walk`] was constructed from, even if it was
471/// advanced before calling [`Walk::inside`]. For a walk constructed through
472/// [`Tree::walk`][crate::Tree::walk] the scope is the whole tree, covering
473/// every root.
474///
475/// # Examples
476///
477/// ```
478/// let tree = syntree::tree! {
479/// "n1" => {
480/// "n3" => {
481/// "n4" => {},
482/// "n5" => {},
483/// }
484/// },
485/// "n6" => {
486/// "n7"
487/// }
488/// };
489///
490/// let values = tree.walk().map(|n| n.value()).collect::<Vec<_>>();
491/// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
492///
493/// let n1 = tree.first().ok_or("missing n1")?;
494///
495/// let values = n1.walk().map(|n| n.value()).collect::<Vec<_>>();
496/// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
497///
498/// let values = n1.walk().inside().map(|n| n.value()).collect::<Vec<_>>();
499/// assert_eq!(values, ["n1", "n3", "n4", "n5"]);
500///
501/// let values = n1.walk_from().inside().map(|n| n.value()).collect::<Vec<_>>();
502/// let empty: [&str; 0] = [];
503/// assert_eq!(values, empty);
504///
505/// let values = tree.walk().inside().map(|n| n.value()).collect::<Vec<_>>();
506/// assert_eq!(values, ["n1", "n3", "n4", "n5", "n6", "n7"]);
507///
508/// # Ok::<_, Box<dyn core::error::Error>>(())
509/// ```
510///
511/// The iterator can be named, for example to store it in a struct:
512///
513/// ```
514/// use syntree::node::Inside;
515/// use syntree::FlavorDefault;
516///
517/// struct Values<'a> {
518/// iter: Inside<'a, &'static str, FlavorDefault>,
519/// }
520///
521/// impl Iterator for Values<'_> {
522/// type Item = &'static str;
523///
524/// fn next(&mut self) -> Option<Self::Item> {
525/// Some(self.iter.next()?.value())
526/// }
527/// }
528///
529/// let tree = syntree::tree! {
530/// "n1" => {
531/// "n2" => {}
532/// },
533/// "n3" => {}
534/// };
535///
536/// let n1 = tree.first().ok_or("missing n1")?;
537/// let values = Values { iter: n1.walk().inside() };
538/// assert_eq!(values.collect::<Vec<_>>(), ["n1", "n2"]);
539/// # Ok::<_, Box<dyn core::error::Error>>(())
540/// ```
541pub struct Inside<'a, T, F>
542where
543 T: Copy,
544 F: Flavor,
545{
546 iter: WalkEvents<'a, T, F>,
547 bounded: bool,
548}
549
550impl<'a, T, F> Iterator for Inside<'a, T, F>
551where
552 T: Copy,
553 F: Flavor,
554{
555 type Item = Node<'a, T, F>;
556
557 #[inline]
558 fn next(&mut self) -> Option<Self::Item> {
559 loop {
560 let (event, node) = self.iter.next()?;
561
562 if self.bounded && self.iter.depth() <= 0 {
563 self.iter = WalkEvents::default();
564 }
565
566 if !matches!(event, Event::Up) {
567 return Some(node);
568 }
569 }
570 }
571}
572
573impl<T, F> FusedIterator for Inside<'_, T, F>
574where
575 T: Copy,
576 F: Flavor,
577{
578}
579
580impl<T, F> Clone for Inside<'_, T, F>
581where
582 T: Copy,
583 F: Flavor,
584{
585 #[inline]
586 fn clone(&self) -> Self {
587 Self {
588 iter: self.iter.clone(),
589 bounded: self.bounded,
590 }
591 }
592}
593
594impl<T, F> Default for Inside<'_, T, F>
595where
596 T: Copy,
597 F: Flavor,
598{
599 #[inline]
600 fn default() -> Self {
601 Self {
602 iter: WalkEvents::default(),
603 bounded: true,
604 }
605 }
606}
607
608impl<T, F> fmt::Debug for Walk<'_, T, F>
609where
610 T: Copy + fmt::Debug,
611 F: Flavor<Index: fmt::Debug>,
612{
613 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614 f.debug_struct("Walk")
615 .field("events", &self.iter)
616 .finish_non_exhaustive()
617 }
618}
619
620impl<T, F> fmt::Debug for WithDepths<'_, T, F>
621where
622 T: Copy + fmt::Debug,
623 F: Flavor<Index: fmt::Debug>,
624{
625 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
626 f.debug_struct("WithDepths")
627 .field("events", &self.iter)
628 .finish()
629 }
630}
631
632impl<T, F> fmt::Debug for Inside<'_, T, F>
633where
634 T: Copy + fmt::Debug,
635 F: Flavor<Index: fmt::Debug>,
636{
637 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
638 f.debug_struct("Inside")
639 .field("events", &self.iter)
640 .finish_non_exhaustive()
641 }
642}