-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6355b39
commit f05a94f
Showing
3 changed files
with
72 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ mod options; | |
mod outcome; | ||
mod output; | ||
mod path; | ||
mod pretty; | ||
mod process; | ||
mod scenario; | ||
mod source; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2021-2023 Martin Pool | ||
|
||
//! Convert a token stream back to (reasonably) pretty Rust code in a string. | ||
use proc_macro2::{Delimiter, TokenTree}; | ||
use quote::ToTokens; | ||
|
||
/// Convert a TokenStream representing some code to a reasonably formatted | ||
/// string of Rust code. | ||
/// | ||
/// [TokenStream] has a `to_string`, but it adds spaces in places that don't | ||
/// look idiomatic, so this reimplements it in a way that looks better. | ||
/// | ||
/// This is probably not correctly formatted for all Rust syntax, and only tries | ||
/// to cover cases that can emerge from the code we generate. | ||
pub(crate) fn tokens_to_pretty_string<T: ToTokens>(t: T) -> String { | ||
use TokenTree::*; | ||
let mut b = String::with_capacity(200); | ||
let mut ts = t.to_token_stream().into_iter().peekable(); | ||
while let Some(tt) = ts.next() { | ||
match tt { | ||
Punct(p) => { | ||
let pc = p.as_char(); | ||
b.push(pc); | ||
if ts.peek().is_some() && (b.ends_with("->") || pc == ',' || pc == ';') { | ||
b.push(' '); | ||
} | ||
} | ||
Ident(_) | Literal(_) => { | ||
match tt { | ||
Literal(l) => b.push_str(&l.to_string()), | ||
Ident(i) => b.push_str(&i.to_string()), | ||
_ => unreachable!(), | ||
}; | ||
if let Some(next) = ts.peek() { | ||
match next { | ||
Ident(_) | Literal(_) => b.push(' '), | ||
Punct(p) => match p.as_char() { | ||
',' | ';' | '<' | '>' | ':' | '.' | '!' => (), | ||
_ => b.push(' '), | ||
}, | ||
Group(_) => (), | ||
} | ||
} | ||
} | ||
Group(g) => { | ||
match g.delimiter() { | ||
Delimiter::Brace => b.push('{'), | ||
Delimiter::Bracket => b.push('['), | ||
Delimiter::Parenthesis => b.push('('), | ||
Delimiter::None => (), | ||
} | ||
b.push_str(&tokens_to_pretty_string(g.stream())); | ||
match g.delimiter() { | ||
Delimiter::Brace => b.push('}'), | ||
Delimiter::Bracket => b.push(']'), | ||
Delimiter::Parenthesis => b.push(')'), | ||
Delimiter::None => (), | ||
} | ||
} | ||
} | ||
} | ||
debug_assert!( | ||
!b.ends_with(' '), | ||
"generated a trailing space: ts={ts:?}, b={b:?}", | ||
ts = t.to_token_stream(), | ||
); | ||
b | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters