1 use crate::algorithm::Printer;
2 use proc_macro2::{Delimiter, Ident, Literal, Spacing, TokenStream, TokenTree};
3 
4 impl Printer {
single_token(&mut self, token: Token, group_contents: fn(&mut Self, TokenStream))5     pub fn single_token(&mut self, token: Token, group_contents: fn(&mut Self, TokenStream)) {
6         match token {
7             Token::Group(delimiter, stream) => self.token_group(delimiter, stream, group_contents),
8             Token::Ident(ident) => self.ident(&ident),
9             Token::Punct(ch, _spacing) => self.token_punct(ch),
10             Token::Literal(literal) => self.token_literal(&literal),
11         }
12     }
13 
token_group( &mut self, delimiter: Delimiter, stream: TokenStream, group_contents: fn(&mut Self, TokenStream), )14     fn token_group(
15         &mut self,
16         delimiter: Delimiter,
17         stream: TokenStream,
18         group_contents: fn(&mut Self, TokenStream),
19     ) {
20         self.delimiter_open(delimiter);
21         if !stream.is_empty() {
22             if delimiter == Delimiter::Brace {
23                 self.space();
24             }
25             group_contents(self, stream);
26             if delimiter == Delimiter::Brace {
27                 self.space();
28             }
29         }
30         self.delimiter_close(delimiter);
31     }
32 
ident(&mut self, ident: &Ident)33     pub fn ident(&mut self, ident: &Ident) {
34         self.word(ident.to_string());
35     }
36 
token_punct(&mut self, ch: char)37     pub fn token_punct(&mut self, ch: char) {
38         self.word(ch.to_string());
39     }
40 
token_literal(&mut self, literal: &Literal)41     pub fn token_literal(&mut self, literal: &Literal) {
42         self.word(literal.to_string());
43     }
44 
delimiter_open(&mut self, delimiter: Delimiter)45     pub fn delimiter_open(&mut self, delimiter: Delimiter) {
46         self.word(match delimiter {
47             Delimiter::Parenthesis => "(",
48             Delimiter::Brace => "{",
49             Delimiter::Bracket => "[",
50             Delimiter::None => return,
51         });
52     }
53 
delimiter_close(&mut self, delimiter: Delimiter)54     pub fn delimiter_close(&mut self, delimiter: Delimiter) {
55         self.word(match delimiter {
56             Delimiter::Parenthesis => ")",
57             Delimiter::Brace => "}",
58             Delimiter::Bracket => "]",
59             Delimiter::None => return,
60         });
61     }
62 }
63 
64 pub enum Token {
65     Group(Delimiter, TokenStream),
66     Ident(Ident),
67     Punct(char, Spacing),
68     Literal(Literal),
69 }
70 
71 impl From<TokenTree> for Token {
from(tt: TokenTree) -> Self72     fn from(tt: TokenTree) -> Self {
73         match tt {
74             TokenTree::Group(group) => Token::Group(group.delimiter(), group.stream()),
75             TokenTree::Ident(ident) => Token::Ident(ident),
76             TokenTree::Punct(punct) => Token::Punct(punct.as_char(), punct.spacing()),
77             TokenTree::Literal(literal) => Token::Literal(literal),
78         }
79     }
80 }
81