1 unstable release
0.1.0 | Feb 24, 2025 |
---|
#226 in Procedural macros
138 downloads per month
9KB
64 lines
Pseudo Rust Module Path Detector
This Rust utility provides a way to determine the module path of a procedural macro invocation. It is particularly useful when writing procedural macros that need to infer their context within a Rust module hierarchy.
✨ Features
- ✅ Detects the module path where the macro is invoked (e.g.,
"crate::task::workflow"
). - ✅ Supports nested modules, both inline (
mod foo {}
) and external (mod foo;
). - ✅ Handles
pub mod
,pub(crate) mod
, andpub(super) mod
declarations correctly. - ✅ Works with procedural macros to automatically infer where they are used.
- ✅ Cross-platform compatibility (handles both
/
and\
in paths).
📦 Installation
This module requires Rust nightly because it uses the proc_macro_span
feature.
-
Add the following to
Cargo.toml
:[dependencies] proc-macro2 = "1"
-
In your Rust crate, enable the nightly feature:
#![feature(proc_macro_span)]
🚀 Usage
This module provides a function get_pseudo_module_path()
that returns the inferred module path as a String
.
Example 1: Simple Module
mod task {
#[some_macro] // This macro should return "crate::task"
fn example() {}
}
Output:
"crate::task"
Example 2: Nested Modules
pub mod task {
pub mod workflow {
#[some_macro] // Should return "crate::task::workflow"
fn example() {}
}
}
Output:
"crate::task::workflow"
Example 3: Procedural Macro Usage
When used inside a procedural macro:
#[proc_macro]
pub fn example_macro(_input: TokenStream) -> TokenStream {
let module_path = get_pseudo_module_path();
println!("Macro invoked in module: {}", module_path);
TokenStream::new()
}
Invoking the macro inside src/workflow.rs
:
workflow::example_macro!();
Output:
Macro invoked in module: "crate::workflow"
🛠️ How It Works
1️⃣ Extracts File and Line Number
It uses proc_macro::Span
to get:
- The file path where the macro was invoked.
- The line number where it was called.
2️⃣ Reads the File and Finds Modules
- Scans the source file above the macro call for module declarations (
mod foo {}
). - Tracks nested modules to build a hierarchical path (
crate::task::workflow
). - Supports both inline (
mod foo {}
) and external (mod foo;
) modules.
3️⃣ Constructs the Full Module Path
- Uses the module hierarchy if found (
crate::task::workflow
). - Otherwise, derives the path from the file structure.
⚠️ Known Limitations
- Requires nightly Rust (
proc_macro_span
feature). - Does not handle generated code (e.g., if a macro generates a module).
- Assumes that module paths match the file structure (standard Rust convention).
👨💻 Contributing
Pull requests and issues are welcome! Feel free to improve the logic or add more test cases.
📜 License
This project is licensed under the MIT License.
Dependencies
~185–610KB
~14K SLoC