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