1use crate::algorithm::Printer;
2use proc_macro2::{Delimiter, Ident, Literal, Spacing, TokenStream, TokenTree};
3
4impl Printer {
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
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
33 pub fn ident(&mut self, ident: &Ident) {
34 self.word(ident.to_string());
35 }
36
37 pub fn token_punct(&mut self, ch: char) {
38 self.word(ch.to_string());
39 }
40
41 pub fn token_literal(&mut self, literal: &Literal) {
42 self.word(literal.to_string());
43 }
44
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
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
64pub enum Token {
65 Group(Delimiter, TokenStream),
66 Ident(Ident),
67 Punct(char, Spacing),
68 Literal(Literal),
69}
70
71impl From<TokenTree> for Token {
72 fn from(tt: TokenTree) -> Self {
73 match tt {
74 TokenTree::Group(group: Group) => Token::Group(group.delimiter(), group.stream()),
75 TokenTree::Ident(ident: Ident) => Token::Ident(ident),
76 TokenTree::Punct(punct: Punct) => Token::Punct(punct.as_char(), punct.spacing()),
77 TokenTree::Literal(literal: Literal) => Token::Literal(literal),
78 }
79 }
80}
81