macro_magic/lib.rs
1//! # Macro Magic 🪄
2//!
3//! 
4//! 
5//! 
6//! 
7//!
8//! ## Overview
9//!
10//! This crate provides an [`#[export_tokens]`](`export_tokens`) attribute macro, and a number
11//! of companion macros, most prominently [`#[import_tokens_proc]`](`import_tokens_proc`) and
12//! [`#[import_tokens_attr]`](`import_tokens_attr`), which, when used in tandem with
13//! [`#[export_tokens]`](`export_tokens`), allow you to create regular and attribute proc
14//! macros in which you can import and make use of the tokens of external/foreign items marked
15//! with [`#[export_tokens]`](`export_tokens`) in other modules, files, and even in other
16//! crates merely by referring to them by name/path.
17//!
18//! Among other things, the patterns introduced by `macro_magic` can be used to implement safe
19//! and efficient exportation and importation of item tokens within the same file, and even
20//! across file and crate boundaries.
21//!
22//! ## no_std
23//!
24//! `macro_magic` is designed to work with stable Rust, and is fully `no_std` compatible (in
25//! fact, there is a unit test to ensure everything is `no_std` safe).
26//!
27//! ## Features
28//!
29//! ### proc_support
30//!
31//! The `proc_support` feature _must_ be enabled in proc macro crates that make use of any
32//! import tokens functionality, including [`#[import_tokens_attr]`](`import_tokens_attr`),
33//! [`#[import_tokens_proc]`](`import_tokens_proc`) and [`import_tokens!`]. Otherwise these
34//! macros will not function correctly and will issue compiler errors complaining about items
35//! not existing under [`mm_core`]. The [`#[export_tokens]`](`export_tokens`) macro does not
36//! require this feature to function correctly, so you can safely use it without enabling this
37//! feature.
38//!
39//! The reason for this feature gating is that things like `syn`, `quote`, `proc_macro2`, etc.,
40//! are not 100% `no_std` compatible and should only be enabled in proc macro crates.
41//!
42//! ## Limitations
43//!
44//! One thing that `macro_magic` _doesn't_ provide is the ability to build up state information
45//! across multiple macro invocations, however this problem can be tackled effectively using
46//! the [outer macro pattern](https://www.youtube.com/watch?v=aEWbZxNCH0A) or in some cases
47//! using static atomics and mutexes in your proc macro crate (which we actually do in this
48//! crate to keep track of unique identifiers).
49//!
50//! ## Breaking Changes
51//!
52//! - **0.4x** removed `#[use_attr]` and `#[use_proc]` (they are no longer needed with the new
53//! self-calling macro style that has been adopted in 0.4x) and also removed the ability to
54//! access `#[export_tokens]` invocations in inaccessible locations like inside of functions
55//! and across module permission boundaries like in an inaccessible private module. This
56//! feature may be re-added in the future if there is interest, however removing it allowed
57//! us to consolidate naming of our `macro_rules!` declarations and remove the need for
58//! `#[use_attr]` / `#[use_proc]`.
59//! - **0.2x** removed and/or re-wrote a number of features that relied on a non-future-proof
60//! behavior of writing/reading files in the `OUT_DIR`. Versions >= 0.2.0 are completely safe
61//! and no longer contain this behavior, however features that provided the ability to
62//! enumerate all the `#[export_tokens]` calls in a namespace have been removed. The proper
63//! way to do this is with the outer macro pattern or with global state mutexes/atomics in
64//! your proc macro crate, as mentioned above.
65//!
66//! More detailed historical change information can be found in
67//! [releases](https://github.com/sam0x17/docify/releases).
68
69#![no_std]
70
71/// Contains the internal code behind the `macro_magic` macros in a re-usable form, in case you
72/// need to design new macros that utilize some of the internal functionality of `macro_magic`.
73pub mod mm_core {
74 #[cfg(feature = "proc_support")]
75 pub use macro_magic_core::*;
76}
77
78pub use macro_magic_macros::{
79 export_tokens, export_tokens_alias, export_tokens_no_emit, forward_tokens,
80 forward_tokens_verbatim, use_attr, use_proc,
81};
82
83#[cfg(feature = "proc_support")]
84pub use macro_magic_macros::{
85 import_tokens, import_tokens_attr, import_tokens_attr_verbatim, import_tokens_proc,
86 with_custom_parsing,
87};
88
89/// Contains re-exports required at compile-time by the macro_magic macros and support
90/// functions.
91#[doc(hidden)]
92pub mod __private {
93 pub use macro_magic_macros::*;
94
95 #[cfg(feature = "proc_support")]
96 pub use quote;
97
98 #[cfg(feature = "proc_support")]
99 pub use syn;
100
101 #[cfg(feature = "proc_support")]
102 pub use syn::__private::TokenStream2;
103}