Skip to main content

syntree/node/
children.rs

1use core::fmt;
2use core::iter::FusedIterator;
3
4use crate::flavor::Flavor;
5use crate::links::Links;
6use crate::node::{Node, SkipTokens};
7use crate::pointer::Pointer;
8
9/// An iterator that iterates over the [`Node::next`] elements of a node. This is
10/// typically used for iterating over the children of a tree.
11///
12/// Note that this iterator also implements [Default], allowing it to
13/// effectively create an empty iterator in case a particular sibling is not
14/// available:
15///
16/// ```
17/// let mut tree = syntree::tree! {
18///     "root" => {
19///         "child1" => {
20///             "child2" => {
21///                 "token1"
22///             }
23///         },
24///         "child3" => {}
25///     }
26/// };
27///
28/// let mut it = tree.first().and_then(|n| n.last()).map(|n| n.children()).unwrap_or_default();
29/// assert_eq!(it.next().map(|n| n.value()), None);
30/// # Ok::<_, Box<dyn core::error::Error>>(())
31/// ```
32///
33/// See [`Tree::children`][crate::Tree::children] or [`Node::children`].
34///
35/// # Examples
36///
37/// ```
38/// let mut tree = syntree::tree! {
39///     "root" => {
40///         "child1" => {
41///             "child2" => {}
42///         },
43///         "child3" => {}
44///     },
45///     "root2" => {
46///         "child4" => {}
47///     }
48/// };
49///
50/// assert_eq!(
51///     tree.children().map(|n| n.value()).collect::<Vec<_>>(),
52///     ["root", "root2"]
53/// );
54///
55/// assert_eq!(
56///     tree.children().rev().map(|n| n.value()).collect::<Vec<_>>(),
57///     ["root2", "root"]
58/// );
59///
60/// let root = tree.first().ok_or("missing root node")?;
61///
62/// assert_eq!(
63///     root.children().map(|n| n.value()).collect::<Vec<_>>(),
64///     ["child1", "child3"]
65/// );
66///
67/// assert_eq!(
68///     root.children().rev().map(|n| n.value()).collect::<Vec<_>>(),
69///     ["child3", "child1"]
70/// );
71/// # Ok::<_, Box<dyn core::error::Error>>(())
72/// ```
73pub struct Children<'a, T, F>
74where
75    T: Copy,
76    F: Flavor,
77{
78    tree: &'a [Links<T, F::Index, F::Pointer>],
79    first: Option<F::Pointer>,
80    last: Option<F::Pointer>,
81}
82
83impl<'a, T, F> Children<'a, T, F>
84where
85    T: Copy,
86    F: Flavor,
87{
88    /// Construct a new child iterator.
89    #[inline]
90    pub(crate) const fn new(
91        tree: &'a [Links<T, F::Index, F::Pointer>],
92        first: Option<F::Pointer>,
93        last: Option<F::Pointer>,
94    ) -> Self {
95        Self { tree, first, last }
96    }
97
98    /// Construct a [`SkipTokens`] iterator from the remainder of this iterator.
99    /// This filters out childless nodes, also known as tokens.
100    ///
101    /// See [`SkipTokens`] for documentation.
102    #[must_use]
103    pub const fn skip_tokens(self) -> SkipTokens<Self> {
104        SkipTokens::new(self)
105    }
106
107    /// Get the next node from the iterator. This advances past all non-node
108    /// data.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// let tree = syntree::tree! {
114    ///     ("token1", 1),
115    ///     "child1" => {
116    ///         "token2"
117    ///     },
118    ///     ("token3", 1),
119    ///     "child2" => {
120    ///         "token4"
121    ///     },
122    ///     ("token5", 1),
123    ///     "child3" => {
124    ///         "token6"
125    ///     },
126    ///     ("token7", 1)
127    /// };
128    ///
129    /// let mut it = tree.children();
130    /// let mut out = Vec::new();
131    ///
132    /// while let Some(n) = it.next_node() {
133    ///     out.push(n.value());
134    /// }
135    ///
136    /// assert_eq!(out, ["child1", "child2", "child3"]);
137    ///
138    /// let mut it = tree.children();
139    ///
140    /// let c1 = it.next_node().ok_or("missing child1")?;
141    /// let c2 = it.next_node().ok_or("missing child2")?;
142    /// let c3 = it.next_node().ok_or("missing child3")?;
143    ///
144    /// assert_eq!([c1.value(), c2.value(), c3.value()], ["child1", "child2", "child3"]);
145    /// # Ok::<_, Box<dyn core::error::Error>>(())
146    /// ```
147    #[inline]
148    pub fn next_node(&mut self) -> Option<Node<'a, T, F>> {
149        self.find(|n| n.has_children())
150    }
151}
152
153impl<'a, T, F> Iterator for Children<'a, T, F>
154where
155    T: Copy,
156    F: Flavor,
157{
158    type Item = Node<'a, T, F>;
159
160    #[inline]
161    fn next(&mut self) -> Option<Self::Item> {
162        let first = self.first.take()?;
163        let node = self.tree.get(first.get())?;
164
165        if first != self.last? {
166            self.first = node.next;
167        }
168
169        Some(Node::new(node, self.tree))
170    }
171
172    #[inline]
173    fn size_hint(&self) -> (usize, Option<usize>) {
174        let lower = self.first.is_some() && self.last.is_some();
175        (usize::from(lower), Some(self.tree.len()))
176    }
177}
178
179impl<T, F> DoubleEndedIterator for Children<'_, T, F>
180where
181    T: Copy,
182    F: Flavor,
183{
184    #[inline]
185    fn next_back(&mut self) -> Option<Self::Item> {
186        let last = self.last.take()?;
187        let node = self.tree.get(last.get())?;
188
189        if last != self.first? {
190            self.last = node.prev;
191        }
192
193        Some(Node::new(node, self.tree))
194    }
195}
196
197impl<T, F> FusedIterator for Children<'_, T, F>
198where
199    T: Copy,
200    F: Flavor,
201{
202}
203
204impl<T, F> Clone for Children<'_, T, F>
205where
206    T: Copy,
207    F: Flavor,
208{
209    #[inline]
210    fn clone(&self) -> Self {
211        Self {
212            tree: self.tree,
213            first: self.first,
214            last: self.last,
215        }
216    }
217}
218
219impl<T, F> Default for Children<'_, T, F>
220where
221    T: Copy,
222    F: Flavor,
223{
224    #[inline]
225    fn default() -> Self {
226        Self {
227            tree: &[],
228            first: None,
229            last: None,
230        }
231    }
232}
233
234impl<T, F> fmt::Debug for Children<'_, T, F>
235where
236    T: Copy + fmt::Debug,
237    F: Flavor<Index: fmt::Debug>,
238{
239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240        let node = |id: Option<F::Pointer>| {
241            let links = self.tree.get(id?.get())?;
242            Some(Node::<T, F>::new(links, self.tree))
243        };
244
245        f.debug_struct("Children")
246            .field("first", &node(self.first))
247            .field("last", &node(self.last))
248            .finish()
249    }
250}