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
}

Read our documentation on viewing source code .

Loading