syntree/node/
siblings.rs

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