1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use proc_macro2::{TokenTree, TokenStream, Punct, Spacing, Delimiter};

pub fn parse<E, F>(toks: TokenStream, mut f: F) -> Result<(), E>
where F: FnMut(&TokenTree) -> Result<(), E>
{
    parse2(toks, &mut f)
}

fn parse2<E>(toks: TokenStream, f: &mut impl FnMut(&TokenTree) -> Result<(), E>)  -> Result<(), E> {
    for tk in toks {
        match tk {
            TokenTree::Group(g) => {
                let (l, r) = match g.delimiter() {
                    Delimiter::Parenthesis => ('(', ')'),
                    Delimiter::Brace => ('{', '}'),
                    Delimiter::Bracket => ('[', ']'),
                    Delimiter::None => (' ', ' '),
                };
                if l != ' ' {
                    f(&TokenTree::Punct(Punct::new(l, Spacing::Alone)))?;
                }
                parse2(g.stream(), f)?;
                if r != ' ' {
                    f(&TokenTree::Punct(Punct::new(r, Spacing::Alone)))?;
                }
            }
            tt => { f(&tt)?; }
        }
    }
    Ok(())
}