aboutsummaryrefslogtreecommitdiff
path: root/mingling_pathf/README.md
blob: 6d8857ab4e70f97d19278d0e562205bd75ea247f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<p align="center">
    <a href="https://github.com/mingling-rs/mingling">
        <img alt="Mingling" src="https://github.com/mingling-rs/mingling/raw/main/docs/res/pixel_icon_core_1024.png" width="30%">
    </a>
</p>
<h1 align="center">Mìng Lìng - Module PathFinder</h1>

## Overview

`mingling_pathf` provides the `pathf` feature for Mingling. It automatically analyzes the full module paths of all Mingling types in a crate at build-time (types defined via `pack!`, `#[derive(Groupped)]`, `#[chain]`, `#[renderer]`, etc.), and generates a mapping from type names to module paths for consumption by `gen_program!()` at compile-time.

When enabled, `gen_program!()` uses full module paths for type references in the generated dispatch code (e.g., `downcast::<myapp::sub::ResultMyName>()`), eliminating the need to `use` all types in the module where `gen_program!()` is called. This allows for a more flexible module organization without the constraint of centralized `use` statements.

## Usage

Enable the `pathf` feature in `Cargo.toml`:

```toml
[dependencies.mingling]
# Used to modify the generation behavior of `gen_program!`
features = ["pathf"] 

[build-dependencies.mingling]
# Provides the `analyze_and_build_type_mapping` function
features = ["builds", "pathf"] 
```

Create a `build.rs` in the project root:

```rust
fn main() {
    mingling::build::analyze_and_build_type_mapping();
}
```

> [!TIP]
> If you already have a `build.rs` (e.g., using `builds` + `comp` features to generate completion scripts), simply add this function call.

## How It Works

1. **Build-time scanning**: `build.rs` traverses all `.rs` source files under `src/`, locating macro invocations such as `pack!`, `#[chain]`, `#[renderer]`, etc., via pattern matching.
2. **Module inference**: The module path is inferred from the file's directory path (e.g., `src/app/sub.rs``app::sub`).
3. **Reference tracking**: Following the chain of `mod use` re-exports (i.e., paths re-exported via `pub use` or `use`), the type name is resolved to the module path under which it is ultimately referenced.
4. **Mapping output**: The mapping from type names to their final referenceable module paths is written to `$OUT_DIR/CRATE_NAME/type-mapping`.
5. **Compile-time consumption**: `gen_program!()` reads this mapping file and uses the full paths for downcasting in the generated dispatch code.

## Constraints

- Does not penetrate secondary indirect expansions of macros (i.e., cannot analyze Mingling type definitions indirectly generated by other macros).