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}