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}