use crate::algorithm::Printer; use proc_macro2::{Delimiter, Ident, Literal, Spacing, TokenStream, TokenTree}; impl Printer { pub fn single_token(&mut self, token: Token, group_contents: fn(&mut Self, TokenStream)) { match token { Token::Group(delimiter, stream) => self.token_group(delimiter, stream, group_contents), Token::Ident(ident) => self.ident(&ident), Token::Punct(ch, _spacing) => self.token_punct(ch), Token::Literal(literal) => self.token_literal(&literal), } } fn token_group( &mut self, delimiter: Delimiter, stream: TokenStream, group_contents: fn(&mut Self, TokenStream), ) { self.delimiter_open(delimiter); if !stream.is_empty() { if delimiter == Delimiter::Brace { self.space(); } group_contents(self, stream); if delimiter == Delimiter::Brace { self.space(); } } self.delimiter_close(delimiter); } pub fn ident(&mut self, ident: &Ident) { self.word(ident.to_string()); } pub fn token_punct(&mut self, ch: char) { self.word(ch.to_string()); } pub fn token_literal(&mut self, literal: &Literal) { self.word(literal.to_string()); } pub fn delimiter_open(&mut self, delimiter: Delimiter) { self.word(match delimiter { Delimiter::Parenthesis => "(", Delimiter::Brace => "{", Delimiter::Bracket => "[", Delimiter::None => return, }); } pub fn delimiter_close(&mut self, delimiter: Delimiter) { self.word(match delimiter { Delimiter::Parenthesis => ")", Delimiter::Brace => "}", Delimiter::Bracket => "]", Delimiter::None => return, }); } } pub enum Token { Group(Delimiter, TokenStream), Ident(Ident), Punct(char, Spacing), Literal(Literal), } impl From for Token { fn from(tt: TokenTree) -> Self { match tt { TokenTree::Group(group) => Token::Group(group.delimiter(), group.stream()), TokenTree::Ident(ident) => Token::Ident(ident), TokenTree::Punct(punct) => Token::Punct(punct.as_char(), punct.spacing()), TokenTree::Literal(literal) => Token::Literal(literal), } } }