Haibo Huang | f5ffad3 | 2020-05-25 23:19:03 -0700 | [diff] [blame] | 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) = self.peeked.take() { |
| 29 | return Some(tt); |
| 30 | } |
| 31 | loop { |
| 32 | let top = self.stack.last_mut()?; |
| 33 | match top.next() { |
| 34 | None => drop(self.stack.pop()), |
| 35 | Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::None => { |
| 36 | self.stack.push(group.stream().into_iter()); |
| 37 | } |
| 38 | Some(tt) => return Some(tt), |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | } |