1
|
|
extern crate proc_macro;
|
2
|
|
extern crate syn;
|
3
|
|
extern crate textwrap;
|
4
|
|
|
5
|
|
use proc_macro::TokenStream;
|
6
|
|
use syn::parse_macro_input;
|
7
|
|
use syn::export::ToTokens;
|
8
|
|
use syn::parse::Parse;
|
9
|
|
use syn::parse::ParseStream;
|
10
|
|
use syn::parse::Result as ParseResult;
|
11
|
|
|
12
|
|
// ---------------------------------------------------------------------------
|
13
|
|
|
14
|
|
struct DedentInput {
|
15
|
|
lit: syn::LitStr
|
16
|
|
}
|
17
|
|
|
18
|
|
impl Parse for DedentInput {
|
19
|
0
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
20
|
0
|
Ok(Self {
|
21
|
0
|
lit: input.parse()?,
|
22
|
|
})
|
23
|
|
}
|
24
|
|
}
|
25
|
|
|
26
|
|
#[proc_macro_hack::proc_macro_hack]
|
27
|
|
pub fn dedent(tokens: TokenStream) -> TokenStream {
|
28
|
|
let input = parse_macro_input!(tokens as DedentInput);
|
29
|
|
let newstr = textwrap::dedent(&input.lit.value());
|
30
|
|
|
31
|
|
syn::LitStr::new(&newstr, input.lit.span())
|
32
|
|
.into_token_stream()
|
33
|
|
.into()
|
34
|
|
}
|
35
|
|
|
36
|
|
// ---------------------------------------------------------------------------
|
37
|
|
|
38
|
|
struct FillInput {
|
39
|
|
lit: syn::LitStr,
|
40
|
|
width: syn::LitInt,
|
41
|
|
}
|
42
|
|
|
43
|
|
impl Parse for FillInput {
|
44
|
0
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
45
|
0
|
let lit = input.parse()?;
|
46
|
0
|
input.parse::<syn::Token![,]>()?;
|
47
|
0
|
let width = input.parse()?;
|
48
|
0
|
Ok(Self { lit, width })
|
49
|
|
}
|
50
|
|
}
|
51
|
|
|
52
|
|
#[proc_macro_hack::proc_macro_hack]
|
53
|
|
pub fn fill(tokens: TokenStream) -> TokenStream {
|
54
|
|
let input = parse_macro_input!(tokens as FillInput);
|
55
|
|
let width = input.width.base10_parse().expect("could not parse number");
|
56
|
|
let newstr = textwrap::fill(&input.lit.value(), width);
|
57
|
|
|
58
|
|
syn::LitStr::new(&newstr, input.lit.span())
|
59
|
|
.into_token_stream()
|
60
|
|
.into()
|
61
|
|
}
|
62
|
|
|
63
|
|
// ---------------------------------------------------------------------------
|
64
|
|
|
65
|
|
struct IndentInput {
|
66
|
|
lit: syn::LitStr,
|
67
|
|
prefix: syn::LitStr,
|
68
|
|
}
|
69
|
|
|
70
|
|
impl Parse for IndentInput {
|
71
|
0
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
72
|
0
|
let lit = input.parse()?;
|
73
|
0
|
input.parse::<syn::Token![,]>()?;
|
74
|
0
|
let prefix = input.parse()?;
|
75
|
0
|
Ok(Self { lit, prefix })
|
76
|
|
}
|
77
|
|
}
|
78
|
|
|
79
|
|
#[proc_macro_hack::proc_macro_hack]
|
80
|
|
pub fn indent(tokens: TokenStream) -> TokenStream {
|
81
|
|
let input = parse_macro_input!(tokens as IndentInput);
|
82
|
|
let newstr = textwrap::indent(&input.lit.value(), &input.prefix.value());
|
83
|
|
|
84
|
|
syn::LitStr::new(&newstr, input.lit.span())
|
85
|
|
.into_token_stream()
|
86
|
|
.into()
|
87
|
|
}
|
88
|
|
|
89
|
|
// ---------------------------------------------------------------------------
|
90
|
|
|
91
|
|
struct WrapInput {
|
92
|
|
lit: syn::LitStr,
|
93
|
|
width: syn::LitInt,
|
94
|
|
}
|
95
|
|
|
96
|
|
impl Parse for WrapInput {
|
97
|
0
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
98
|
0
|
let lit = input.parse()?;
|
99
|
0
|
input.parse::<syn::Token![,]>()?;
|
100
|
0
|
let width = input.parse()?;
|
101
|
0
|
Ok(Self { lit, width })
|
102
|
|
}
|
103
|
|
}
|
104
|
|
|
105
|
|
#[proc_macro_hack::proc_macro_hack]
|
106
|
|
pub fn wrap(tokens: TokenStream) -> TokenStream {
|
107
|
|
let input = parse_macro_input!(tokens as WrapInput);
|
108
|
|
let width = input.width.base10_parse().expect("could not parse number");
|
109
|
|
|
110
|
|
let elems = textwrap::wrap_iter(&input.lit.value(), width)
|
111
|
|
.map(|s| syn::Lit::from(syn::LitStr::new(&s, input.lit.span())))
|
112
|
|
.map(|lit| syn::Expr::Lit(syn::ExprLit { lit, attrs: Vec::new() }))
|
113
|
|
.collect();
|
114
|
|
let array = syn::ExprArray {
|
115
|
|
elems,
|
116
|
|
attrs: Vec::new(),
|
117
|
|
bracket_token: Default::default(),
|
118
|
|
};
|
119
|
|
let expr = syn::ExprReference {
|
120
|
|
attrs: Vec::new(),
|
121
|
|
and_token: Default::default(),
|
122
|
|
raw: Default::default(),
|
123
|
|
mutability: None,
|
124
|
|
expr: Box::new(syn::Expr::Array(array)),
|
125
|
|
};
|
126
|
|
|
127
|
|
expr.into_token_stream().into()
|
128
|
|
}
|