abi_stable_derive/
workaround.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Wrote this as a workaround for
//! `<TokenStream as Display>::fmt` not working correctly for some reason.

use std::{fmt::Write, mem};

use proc_macro2::{Delimiter, Spacing, TokenStream as TokenStream2, TokenTree};

use core_extensions::SelfOps;

struct WriteState {
    add_spacing_before: bool,
}

fn write_token_tree_inner(tt: TokenTree, s: &mut String, state: &mut WriteState) {
    let _added_spacing = mem::replace(&mut state.add_spacing_before, false);

    match tt {
        TokenTree::Group(group) => {
            let (start, end) = match group.delimiter() {
                Delimiter::Parenthesis => ('(', ')'),
                Delimiter::Brace => ('{', '}'),
                Delimiter::Bracket => ('[', ']'),
                Delimiter::None => (' ', ' '),
            };
            let _ = write!(s, "{} ", start);
            for nested_tt in group.stream() {
                write_token_tree(nested_tt, s);
            }
            state.add_spacing_before = false;
            let _ = write!(s, " {}", end);
        }
        TokenTree::Ident(x) => write!(s, "{} ", x).drop_(),
        TokenTree::Punct(punct) => {
            // if added_spacing {
            //     s.push(' ');
            // }
            s.push(punct.as_char());
            state.add_spacing_before = match punct.spacing() {
                Spacing::Alone => {
                    s.push(' ');
                    true
                }
                // Spacing::Alone=>true,
                Spacing::Joint => false,
            }
        }
        TokenTree::Literal(x) => write!(s, "{} ", x).drop_(),
    }
}

fn write_token_tree(tt: TokenTree, s: &mut String) {
    write_token_tree_inner(
        tt,
        s,
        &mut WriteState {
            add_spacing_before: false,
        },
    )
}

pub fn write_token_stream(ts: TokenStream2, buffer: &mut String) {
    for tt in ts {
        write_token_tree(tt, buffer);
    }
}

pub fn token_stream_to_string(ts: TokenStream2) -> String {
    let mut buffer = String::new();
    write_token_stream(ts, &mut buffer);
    buffer
}