syntree/node/ancestors.rs
1use core::fmt;
2use core::iter::FusedIterator;
3
4use crate::flavor::Flavor;
5use crate::node::{Node, SkipTokens};
6
7/// An iterator that iterates over the [`Node::parent`] elements of a node. This
8/// is used for iterating over the ancestors of a node.
9///
10/// Note that this iterator also implements [Default], allowing it to
11/// effectively create an empty iterator in case a particular ancestor is not
12/// available:
13///
14/// ```
15/// let mut tree = syntree::tree! {
16/// "root" => {
17/// "child1" => {},
18/// "child3" => {}
19/// }
20/// };
21///
22/// let mut it = tree.first().and_then(|n| n.first()).and_then(|n| n.first()).map(|n| n.ancestors()).unwrap_or_default();
23/// assert!(it.next().is_none());
24/// # Ok::<_, Box<dyn core::error::Error>>(())
25/// ```
26///
27/// See [`Node::ancestors`].
28///
29/// # Examples
30///
31/// ```
32/// let mut tree = syntree::tree! {
33/// "root" => {
34/// "child1" => {
35/// "child2" => {}
36/// },
37/// "child3" => {}
38/// }
39/// };
40///
41/// let child2 = tree.first().and_then(|n| n.first()).and_then(|n| n.first()).ok_or("missing child2")?;
42/// assert_eq!(child2.value(), "child2");
43///
44/// assert_eq!(
45/// child2.ancestors().map(|n| n.value()).collect::<Vec<_>>(),
46/// ["child2", "child1", "root"]
47/// );
48/// # Ok::<_, Box<dyn core::error::Error>>(())
49/// ```
50pub struct Ancestors<'a, T, F>
51where
52 T: Copy,
53 F: Flavor,
54{
55 node: Option<Node<'a, T, F>>,
56}
57
58impl<'a, T, F> Ancestors<'a, T, F>
59where
60 T: Copy,
61 F: Flavor,
62{
63 /// Construct a new ancestor iterator.
64 #[inline]
65 pub(crate) const fn new(node: Option<Node<'a, T, F>>) -> Self {
66 Self { node }
67 }
68
69 /// Construct a [`SkipTokens`] iterator from the remainder of this iterator.
70 /// This filters out childless nodes, also known as tokens.
71 ///
72 /// See [`SkipTokens`] for documentation.
73 #[inline]
74 #[must_use]
75 pub const fn skip_tokens(self) -> SkipTokens<Self> {
76 SkipTokens::new(self)
77 }
78
79 /// Get the next node from the iterator. This advances past all non-node
80 /// data.
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// let tree = syntree::tree! {
86 /// "root" => {
87 /// "child" => {
88 /// ("lit", 3)
89 /// }
90 /// }
91 /// };
92 ///
93 /// let lit = tree.first().and_then(|n| n.first()?.first()).ok_or("missing lit")?;
94 /// assert_eq!(lit.value(), "lit");
95 ///
96 /// let mut it = lit.ancestors();
97 /// let mut out = Vec::new();
98 ///
99 /// while let Some(n) = it.next_node() {
100 /// out.push(n.value());
101 /// }
102 ///
103 /// assert_eq!(out, ["child", "root"]);
104 ///
105 /// let mut it = lit.ancestors();
106 ///
107 /// let child = it.next_node().ok_or("missing child")?;
108 /// let root = it.next_node().ok_or("missing root")?;
109 ///
110 /// assert_eq!([child.value(), root.value()], ["child", "root"]);
111 /// # Ok::<_, Box<dyn core::error::Error>>(())
112 /// ```
113 #[inline]
114 pub fn next_node(&mut self) -> Option<Node<'a, T, F>> {
115 self.find(|n| n.has_children())
116 }
117}
118
119impl<'a, T, F> Iterator for Ancestors<'a, T, F>
120where
121 T: Copy,
122 F: Flavor,
123{
124 type Item = Node<'a, T, F>;
125
126 #[inline]
127 fn next(&mut self) -> Option<Self::Item> {
128 let node = self.node.take()?;
129 self.node = node.parent();
130 Some(node)
131 }
132
133 #[inline]
134 fn size_hint(&self) -> (usize, Option<usize>) {
135 (usize::from(self.node.is_some()), None)
136 }
137}
138
139impl<T, F> FusedIterator for Ancestors<'_, T, F>
140where
141 T: Copy,
142 F: Flavor,
143{
144}
145
146impl<T, F> Clone for Ancestors<'_, T, F>
147where
148 T: Copy,
149 F: Flavor,
150{
151 #[inline]
152 fn clone(&self) -> Self {
153 Self { node: self.node }
154 }
155}
156
157impl<T, F> Default for Ancestors<'_, T, F>
158where
159 T: Copy,
160 F: Flavor,
161{
162 #[inline]
163 fn default() -> Self {
164 Self { node: None }
165 }
166}
167
168impl<T, F> fmt::Debug for Ancestors<'_, T, F>
169where
170 T: Copy + fmt::Debug,
171 F: Flavor<Index: fmt::Debug>,
172{
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 f.debug_struct("Ancestors")
175 .field("next", &self.node)
176 .finish()
177 }
178}