Macro mini_macro_magic::export
source · macro_rules! export { { #[export( $(#[$($attr:tt)*])* $name:ident $dollar:tt )] { $($t:tt)* } } => { ... }; { #[export( $(#[$($attr:tt)*])* pub($($module:tt)*) $name:ident $dollar:tt )] { $($t:tt)* } } => { ... }; { #[export( $(#[$($attr:tt)*])* pub $name:ident $dollar:tt )] { $($t:tt)* } } => { ... }; { #[export( $(#[$($attr:tt)*])* pub crate $name:ident $dollar:tt )] { $($t:tt)* } } => { ... }; {$($t:tt)*} => { ... }; }
Expand description
Export tokens for later inspection by other macros.
This macro enables exporting arbitrary token sequences to other modules or even crates. Call the macro with the following form.
export!(
#[export(
/// Any extra docs you want.
<visibility> <macro name>$
)]
{
<some arbitrary tokens>
}
);
This will generate a macro_rules!
with the name given at <macro name>
.
Any docs given in the export
attribute will be added to the top of the macro
docs. The macro is already given a set of basic docs and an example (see example::demo_struct
for what this basic docs looks like).
<visibility>
can be any of the normal visibility specifiers (nothing, pub
, pub(crate)
,
pub(super)
, …). It can also be pub crate
which has a special meaning. pub crate
is used
when in the root of a crate (main.rs
or lib.rs
) and we want the macro to be public outside
the crate. This is needed because the normal visibility specifiers don’t work there.
The public visibility specifiers also automatically put the macro’s docs in the module
export
was invoked in instead of having the macro docs at the root of the crate.
The $
after the macro name is always required. This is do to a limitation of macro_ruiles!
where $
can’t be escaped.
The form above was chossen because it allows code formatting to work as you would expect.
Any code in <some arbitrary tokens>
is seen by rustfmt as a normal expression and can be
formatted accordingly. rustfmt will not format the export
attribute though.
Note: The docs generated for the macro include a doc test example. The doc test should always
pass (if it doesn’t please post an issue). However, sometimes this
may not be wanted. To disable the doc test generation (it will be generated as a text code
block instead) add the mmm_no_gen_examples
cfg item (its not a feature) when compiling.
macro_rules_attribute
Support
There is also another form export
can be called with designed for use with the
macro_rules_attribute
crate.
export!(
/// Any docs or attributes for the item (not the macro).
#[custom(export(
/// Any extra docs you want.
<visibility> <macro name>$
))]
<some arbitrary tokens>
);
When used with the macro_rules_attribute::derive
macro this allows the following.
/// Some docs for `Demo`.
#[derive(export!)]
#[custom(export(
pub demo_struct$
))]
struct Demo {
pub name: String,
}
Examples
See the integration tests for examples
that show why you would want to use export
.
export!(
#[export(
demo_struct$
)]
{
struct Demo {
pub name: String,
}
}
);
export!(
#[export(
pub a_plus_b$
)]
{
a + b
}
);
export!(
#[export(
/// Some docs.
pub(crate) allow_unused$
)]
{
#[allow(unused)]
}
);
Invalid Input
If export
is called with incorrect syntax a compile error will be generated with the
expected calling syntax and the syntax it was given.
export!(
#[export(demo_struct)]
{
struct Demo {
pub name: String,
}
}
);
error: `export!()` expects input of the form:
#[export(<vis> <name>$)] { <tokens> }
instead got:
#[export(demo_struct)] { struct Demo { pub name : String, } }
--> src/lib.rs:132:1
|
6 | / export!(
7 | | #[export(demo_struct)]
8 | | {
9 | | struct Demo {
... |
12 | | }
13 | | );
| |_^