stringify_attr/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use quote::{quote, ToTokens};
4use std::fmt::Display;
5
6fn stringify_helper(result: impl ToTokens) -> TokenStream2 {
7    quote!(
8        macro_rules! result {
9            () => { #result }
10        }
11    )
12}
13fn stringify_all_helper(open: char, close: &'static str, attr: impl Display, item: impl Display) -> TokenStream2 {
14    let result = format!("#[stringify_all{}{}{}] {}", open, attr, close, item);
15    stringify_helper(result)
16}
17
18/// Creates a macro `result` which expands to the same string literal as
19/// `stringify!(attr)`
20#[proc_macro_attribute]
21pub fn stringify_attr(attr: TokenStream, _item: TokenStream) -> TokenStream {
22    stringify_helper(attr.to_string()).into()
23}
24
25/// Creates a macro `result` which expands to the same string literal as
26/// `stringify!(item)`
27#[proc_macro_attribute]
28pub fn stringify_item(_attr: TokenStream, item: TokenStream) -> TokenStream {
29    stringify_helper(item.to_string()).into()
30}
31
32/// An alias for `stringify_parens`
33#[proc_macro_attribute]
34pub fn stringify_all(attr: TokenStream, item: TokenStream) -> TokenStream {
35    stringify_parens(attr, item)
36}
37
38/// Creates a macro `result` which expands to the same string literal as
39/// `concat!("#[stringify_all(", stringify!(attr), ")]", stringify!(item))`
40#[proc_macro_attribute]
41pub fn stringify_parens(attr: TokenStream, item: TokenStream) -> TokenStream {
42    stringify_all_helper('(', ")", attr, item).into()
43}
44
45/// Creates a macro `result` which expands to the same string literal as
46/// `concat!("#[stringify_all{", stringify!(attr), "}]", stringify!(item))`
47#[proc_macro_attribute]
48pub fn stringify_braces(attr: TokenStream, item: TokenStream) -> TokenStream {
49    stringify_all_helper('{', "}", attr, item).into()
50}
51
52/// Creates a macro `result` which expands to the same string literal as
53/// `concat!("#[stringify_all[", stringify!(attr), "]]", stringify!(item))`
54#[proc_macro_attribute]
55pub fn stringify_brackets(attr: TokenStream, item: TokenStream) -> TokenStream {
56    stringify_all_helper('[', "]", attr, item).into()
57}
58
59/// Creates a macro `result` which expands to the same string literal as
60/// `concat!("#[stringify_all=", stringify!(attr), "]", stringify!(item))`
61#[doc(hidden)]
62#[proc_macro_attribute]
63pub fn stringify_eq(attr: TokenStream, item: TokenStream) -> TokenStream {
64    stringify_all_helper('=', "", attr, item).into()
65}
66
67#[cfg(test)]
68mod test {
69    use super::{stringify_helper, stringify_all_helper};
70    use quote::quote;
71
72    #[test]
73    fn stringify_helper_simple() {
74        assert_eq!(
75            stringify_helper("foo").to_string(),
76            quote!( macro_rules! result { () => { "foo" } } ).to_string(),
77        );
78    }
79
80    #[test]
81    fn stringify_all_simple() {
82        assert_eq!(
83            stringify_all_helper('{', "}", "foo", "bar").to_string(),
84            quote!( macro_rules! result { () => { "#[stringify_all{foo}] bar" } } ).to_string(),
85        );
86    }
87}