abi_stable_derive/
workaround.rs
1use std::{fmt::Write, mem};
5
6use proc_macro2::{Delimiter, Spacing, TokenStream as TokenStream2, TokenTree};
7
8use core_extensions::SelfOps;
9
10struct WriteState {
11 add_spacing_before: bool,
12}
13
14fn write_token_tree_inner(tt: TokenTree, s: &mut String, state: &mut WriteState) {
15 let _added_spacing = mem::replace(&mut state.add_spacing_before, false);
16
17 match tt {
18 TokenTree::Group(group) => {
19 let (start, end) = match group.delimiter() {
20 Delimiter::Parenthesis => ('(', ')'),
21 Delimiter::Brace => ('{', '}'),
22 Delimiter::Bracket => ('[', ']'),
23 Delimiter::None => (' ', ' '),
24 };
25 let _ = write!(s, "{} ", start);
26 for nested_tt in group.stream() {
27 write_token_tree(nested_tt, s);
28 }
29 state.add_spacing_before = false;
30 let _ = write!(s, " {}", end);
31 }
32 TokenTree::Ident(x) => write!(s, "{} ", x).drop_(),
33 TokenTree::Punct(punct) => {
34 s.push(punct.as_char());
38 state.add_spacing_before = match punct.spacing() {
39 Spacing::Alone => {
40 s.push(' ');
41 true
42 }
43 Spacing::Joint => false,
45 }
46 }
47 TokenTree::Literal(x) => write!(s, "{} ", x).drop_(),
48 }
49}
50
51fn write_token_tree(tt: TokenTree, s: &mut String) {
52 write_token_tree_inner(
53 tt,
54 s,
55 &mut WriteState {
56 add_spacing_before: false,
57 },
58 )
59}
60
61pub fn write_token_stream(ts: TokenStream2, buffer: &mut String) {
62 for tt in ts {
63 write_token_tree(tt, buffer);
64 }
65}
66
67pub fn token_stream_to_string(ts: TokenStream2) -> String {
68 let mut buffer = String::new();
69 write_token_stream(ts, &mut buffer);
70 buffer
71}