macro_v/lib.rs
1#![doc = include_str!("../README.md")]
2
3mod v;
4
5use proc_macro::TokenStream;
6use syn::{parse_macro_input, Visibility};
7use v::MacroDefinition;
8
9/// Attribute that make the visibility of the `macro_rules!` macro the same as
10/// other items.
11///
12/// So the usage of `#[macro-v]` is private by default, as is the visibility of
13/// other items. For example:
14///
15/// ```rust
16/// // Use before declaration
17/// private_macro!();
18///
19/// #[macro_v]
20/// macro_rules! private_macro {
21/// () => {};
22/// }
23///
24/// mod inner {
25/// // You must use the prefix `super::` or `crate::` to call the macro,
26/// // because it is not in the current scope
27/// super::private_macro!();
28/// crate::private_macro!();
29/// }
30/// ```
31///
32/// You can also use `#[macro_v(pub(crate))]` to make the macro visible in the
33/// current crate. For example:
34///
35/// ```rust
36/// inner::example_macro!();
37///
38/// // No `#[macro_use]` needed!
39/// mod inner {
40/// use macro_v::macro_v;
41///
42/// #[macro_v(pub(crate))]
43/// macro_rules! example_macro {
44/// () => {};
45/// }
46/// }
47/// ```
48///
49/// Defining public macros also no longer requires `#[macro_export]`, but
50/// instead uses `#[macro-v(pub)]`. For example:
51///
52/// ```rust
53/// pub mod inner {
54/// use macro_v::macro_v;
55///
56/// #[macro_v(pub)]
57/// macro_rules! public_macro {
58/// () => {};
59/// }
60/// }
61///
62/// crate::inner::public_macro!();
63/// ```
64#[proc_macro_attribute]
65pub fn macro_v(attr: TokenStream, item: TokenStream) -> TokenStream {
66 let vis = parse_macro_input!(attr as Visibility);
67 let macro_def = parse_macro_input!(item as MacroDefinition);
68
69 v::generate(vis, macro_def)
70 .unwrap_or_else(|err| err.to_compile_error())
71 .into()
72}