const_fn/
iter.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3// Based on https://github.com/dtolnay/proc-macro-hack/blob/0.5.19/src/iter.rs
4
5use 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}