Skip to main content

syntree/node/
siblings.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 a node and its [`Node::next`] siblings.
10/// Previous siblings are not included.
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///             "token2"
26///         }
27///     }
28/// };
29///
30/// let mut it = tree.first().and_then(|n| n.next()).map(|n| n.siblings()).unwrap_or_default();
31/// assert_eq!(it.next().map(|n| n.value()), None);
32/// # Ok::<_, Box<dyn core::error::Error>>(())
33/// ```
34///
35/// See [`Node::siblings`].
36///
37/// # Examples
38///
39/// ```
40/// let mut tree = syntree::tree! {
41///     "root" => {
42///         "child1" => {
43///             "child2" => {
44///                 "token1"
45///             }
46///         },
47///         "child3" => {
48///             "token2"
49///         }
50///     },
51///     "root2" => {
52///         "child4" => {
53///             "token3"
54///         }
55///     }
56/// };
57///
58/// let root = tree.first().ok_or("missing root")?;
59///
60/// assert_eq!(
61///     root.siblings().map(|n| n.value()).collect::<Vec<_>>(),
62///     ["root", "root2"]
63/// );
64/// # Ok::<_, Box<dyn core::error::Error>>(())
65/// ```
66pub struct Siblings<'a, T, F>
67where
68    T: Copy,
69    F: Flavor,
70{
71    tree: &'a [Links<T, F::Index, F::Pointer>],
72    links: Option<&'a Links<T, F::Index, F::Pointer>>,
73}
74
75impl<'a, T, F> Siblings<'a, T, F>
76where
77    T: Copy,
78    F: Flavor,
79{
80    /// Construct a new sibling iterator starting at the given node.
81    #[inline]
82    pub(crate) const fn new(
83        tree: &'a [Links<T, F::Index, F::Pointer>],
84        links: &'a Links<T, F::Index, F::Pointer>,
85    ) -> Self {
86        Self {
87            tree,
88            links: Some(links),
89        }
90    }
91
92    /// Construct a [`SkipTokens`] iterator from the remainder of this iterator.
93    /// This filters out childless nodes, also known as tokens.
94    ///
95    /// See [`SkipTokens`] for documentation.
96    #[must_use]
97    pub const fn skip_tokens(self) -> SkipTokens<Self> {
98        SkipTokens::new(self)
99    }
100
101    /// Get the next node from the iterator. This advances past all non-node
102    /// data.
103    ///
104    /// # Examples
105    ///
106    /// ```
107    /// let tree = syntree::tree! {
108    ///     ("token1", 1),
109    ///     "child1" => {
110    ///         "token2"
111    ///     },
112    ///     ("token3", 1),
113    ///     "child2" => {
114    ///         "token4"
115    ///     },
116    ///     ("token5", 1),
117    ///     "child3" => {
118    ///         "token6"
119    ///     },
120    ///     ("token7", 1)
121    /// };
122    ///
123    /// let first = tree.first().ok_or("missing first")?;
124    ///
125    /// let mut it = first.siblings();
126    /// let mut out = Vec::new();
127    ///
128    /// while let Some(n) = it.next_node() {
129    ///     out.push(n.value());
130    /// }
131    ///
132    /// assert_eq!(out, ["child1", "child2", "child3"]);
133    ///
134    /// let mut it = first.siblings();
135    ///
136    /// let c1 = it.next_node().ok_or("missing child1")?;
137    /// let c2 = it.next_node().ok_or("missing child2")?;
138    /// let c3 = it.next_node().ok_or("missing child3")?;
139    ///
140    /// assert_eq!([c1.value(), c2.value(), c3.value()], ["child1", "child2", "child3"]);
141    /// # Ok::<_, Box<dyn core::error::Error>>(())
142    /// ```
143    #[inline]
144    pub fn next_node(&mut self) -> Option<Node<'a, T, F>> {
145        self.find(|n| n.has_children())
146    }
147}
148
149impl<'a, T, F> Iterator for Siblings<'a, T, F>
150where
151    T: Copy,
152    F: Flavor,
153{
154    type Item = Node<'a, T, F>;
155
156    #[inline]
157    fn next(&mut self) -> Option<Self::Item> {
158        let links = self.links.take()?;
159        self.links = links.next.and_then(|id| self.tree.get(id.get()));
160        Some(Node::new(links, self.tree))
161    }
162
163    #[inline]
164    fn size_hint(&self) -> (usize, Option<usize>) {
165        (usize::from(self.links.is_some()), Some(self.tree.len()))
166    }
167}
168
169impl<T, F> FusedIterator for Siblings<'_, T, F>
170where
171    T: Copy,
172    F: Flavor,
173{
174}
175
176impl<T, F> Clone for Siblings<'_, T, F>
177where
178    T: Copy,
179    F: Flavor,
180{
181    #[inline]
182    fn clone(&self) -> Self {
183        Self {
184            tree: self.tree,
185            links: self.links,
186        }
187    }
188}
189
190impl<T, F> Default for Siblings<'_, T, F>
191where
192    T: Copy,
193    F: Flavor,
194{
195    #[inline]
196    fn default() -> Self {
197        Self {
198            tree: &[],
199            links: None,
200        }
201    }
202}
203
204impl<T, F> fmt::Debug for Siblings<'_, T, F>
205where
206    T: Copy + fmt::Debug,
207    F: Flavor<Index: fmt::Debug>,
208{
209    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210        let next = self.links.map(|links| Node::<T, F>::new(links, self.tree));
211        f.debug_struct("Siblings").field("next", &next).finish()
212    }
213}