syntree/node/skip_tokens.rs
1use core::iter::FusedIterator;
2
3use crate::flavor::Flavor;
4use crate::node::Node;
5
6/// Wrapped around an iterator that excludes nodes without children.
7///
8/// See [`Siblings::skip_tokens`] or [`Walk::skip_tokens`].
9///
10/// [`Siblings::skip_tokens`]: crate::node::Siblings::skip_tokens
11/// [`Walk::skip_tokens`]: crate::node::Walk::skip_tokens
12///
13/// # Examples
14///
15/// Filtering childless nodes from a [`Siblings`] iterator:
16///
17/// ```
18/// let tree = syntree::tree! {
19/// ("token1", 1),
20/// "child1" => {
21/// "token2"
22/// },
23/// ("token3", 1),
24/// "child2" => {
25/// "toke4"
26/// },
27/// ("token5", 1),
28/// "child3" => {
29/// "token6"
30/// },
31/// ("token7", 1)
32/// };
33///
34/// let mut it = tree.children().skip_tokens();
35///
36/// assert_eq!(
37/// it.map(|n| n.value()).collect::<Vec<_>>(),
38/// ["child1", "child2", "child3"]
39/// );
40/// # Ok::<_, Box<dyn core::error::Error>>(())
41/// ```
42///
43/// Filtering tokens from a [`Walk`] iterator:
44///
45/// ```
46/// let tree = syntree::tree! {
47/// "child1" => {
48/// "child2" => {
49/// "token1"
50/// },
51/// ("token2", 1),
52/// "child3" => {
53/// "token3"
54/// },
55/// },
56/// "child4" => {
57/// ("token4", 1)
58/// }
59/// };
60///
61/// let mut it = tree.walk().skip_tokens();
62///
63/// assert_eq!(
64/// it.map(|n| n.value()).collect::<Vec<_>>(),
65/// ["child1", "child2", "child3", "child4"]
66/// );
67/// # Ok::<_, Box<dyn core::error::Error>>(())
68/// ```
69///
70/// [`Siblings`]: crate::node::Siblings
71/// [`Walk`]: crate::node::Walk
72pub struct SkipTokens<U> {
73 iter: U,
74}
75
76impl<U> SkipTokens<U> {
77 #[inline]
78 pub(crate) const fn new(iter: U) -> Self {
79 Self { iter }
80 }
81}
82
83impl<'a, U, T: 'a, F: 'a> Iterator for SkipTokens<U>
84where
85 T: Copy,
86 F: Flavor,
87 U: Iterator<Item = Node<'a, T, F>>,
88{
89 type Item = U::Item;
90
91 #[inline]
92 fn next(&mut self) -> Option<Self::Item> {
93 self.iter.find(|n| n.has_children())
94 }
95
96 #[inline]
97 fn size_hint(&self) -> (usize, Option<usize>) {
98 let (_, upper) = self.iter.size_hint();
99 (0, upper)
100 }
101
102 #[inline]
103 fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
104 where
105 Self: Sized,
106 P: FnMut(&Self::Item) -> bool,
107 {
108 self.iter.find(move |n| n.has_children() && predicate(n))
109 }
110}
111
112impl<'a, U, T: 'a, F: 'a> DoubleEndedIterator for SkipTokens<U>
113where
114 T: Copy,
115 F: Flavor,
116 U: DoubleEndedIterator<Item = Node<'a, T, F>>,
117{
118 #[inline]
119 fn next_back(&mut self) -> Option<Self::Item> {
120 self.iter.rfind(|n| n.has_children())
121 }
122
123 #[inline]
124 fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
125 where
126 Self: Sized,
127 P: FnMut(&Self::Item) -> bool,
128 {
129 self.iter.rfind(move |n| n.has_children() && predicate(n))
130 }
131}
132
133impl<'a, U, T: 'a, F: 'a> FusedIterator for SkipTokens<U>
134where
135 T: Copy,
136 F: Flavor,
137 U: FusedIterator<Item = Node<'a, T, F>>,
138{
139}
140
141impl<U> Clone for SkipTokens<U>
142where
143 U: Clone,
144{
145 #[inline]
146 fn clone(&self) -> Self {
147 Self {
148 iter: self.iter.clone(),
149 }
150 }
151}
152
153impl<U> Default for SkipTokens<U>
154where
155 U: Default,
156{
157 #[inline]
158 fn default() -> Self {
159 Self {
160 iter: Default::default(),
161 }
162 }
163}