1use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};
6
7pub(crate) struct TokenIter {
8 stack: Vec<token_stream::IntoIter>,
9 peeked: Option<TokenTree>,
10}
11
12impl TokenIter {
13 pub(crate) fn new(tokens: TokenStream) -> Self {
14 Self { stack: vec![tokens.into_iter()], peeked: None }
15 }
16
17 pub(crate) fn peek(&mut self) -> Option<&TokenTree> {
18 self.peeked = self.next();
19 self.peeked.as_ref()
20 }
21}
22
23impl Iterator for TokenIter {
24 type Item = TokenTree;
25
26 fn next(&mut self) -> Option<Self::Item> {
27 if let Some(tt) = self.peeked.take() {
28 return Some(tt);
29 }
30 loop {
31 let top = self.stack.last_mut()?;
32 match top.next() {
33 None => drop(self.stack.pop()),
34 Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::None => {
35 self.stack.push(group.stream().into_iter());
36 }
37 Some(tt) => return Some(tt),
38 }
39 }
40 }
41}