1use proc_macro2::{TokenTree, TokenStream, Punct, Spacing, Delimiter};
2
3pub fn parse<E, F>(toks: TokenStream, mut f: F) -> Result<(), E>
4where F: FnMut(&TokenTree) -> Result<(), E>
5{
6 parse2(toks, &mut f)
7}
8
9fn parse2<E>(toks: TokenStream, f: &mut impl FnMut(&TokenTree) -> Result<(), E>) -> Result<(), E> {
10 for tk in toks {
11 match tk {
12 TokenTree::Group(g) => {
13 let (l, r) = match g.delimiter() {
14 Delimiter::Parenthesis => ('(', ')'),
15 Delimiter::Brace => ('{', '}'),
16 Delimiter::Bracket => ('[', ']'),
17 Delimiter::None => (' ', ' '),
18 };
19 if l != ' ' {
20 f(&TokenTree::Punct(Punct::new(l, Spacing::Alone)))?;
21 }
22 parse2(g.stream(), f)?;
23 if r != ' ' {
24 f(&TokenTree::Punct(Punct::new(r, Spacing::Alone)))?;
25 }
26 }
27 tt => { f(&tt)?; }
28 }
29 }
30 Ok(())
31}