abi_stable_derive/
workaround.rs

1//! Wrote this as a workaround for
2//! `<TokenStream as Display>::fmt` not working correctly for some reason.
3
4use 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            // if added_spacing {
35            //     s.push(' ');
36            // }
37            s.push(punct.as_char());
38            state.add_spacing_before = match punct.spacing() {
39                Spacing::Alone => {
40                    s.push(' ');
41                    true
42                }
43                // Spacing::Alone=>true,
44                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}