diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-19 00:47:32 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-19 00:47:32 +0800 |
| commit | b06782c69ce77f64ef19295d2727248ed72c07b5 (patch) | |
| tree | 6c1068588e9422b40b1bfe1ba6e5c8b9cbcd8979 | |
| parent | e553c0fc22ae99251d3954ae248216ec9bf68e3f (diff) | |
docs: update README and add ROADMAP with contributors section
| -rw-r--r-- | CONTRIBUTING.md | 38 | ||||
| -rw-r--r-- | README.md | 173 | ||||
| -rw-r--r-- | ROADMAP.md | 33 |
3 files changed, 147 insertions, 97 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f86c3d..6e34e93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,24 +6,24 @@ Before contributing, we recommend reading [README](README.md) to get an overview ## 1. Project Structure 📦 -| Category | Path/Name | Description | -| --------------------------- | -------------------- | -------------------------------------------------------------------- | -| **Entry crate** | `mingling/` | Project entry point | -| **Core library** | `mingling_core/` | Imported as an external dependency | -| **Macro library** | `mingling_macros/` | Imported as an external dependency | -| **Mingling Pathfinder** | `mingling_pathf/` | Build-time module path resolution for types | -| **Mingling Picker2** | `arg_picker/` | Mingling Arguments Parser | -| **Mingling Picker2 Macros** | `arg_picker_macros/` | Mingling Arguments Parser Macros | -| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` | -| **Examples** | `examples/` | To add expected output tests, add a `test.toml` in the example's dir | -| **Documents** | `docs/` | All documents | -| **Dev Documents** | `docs/dev/` | Internal documents | -| **Resources** | `docs/res/` | All resources | -| **CI system** | `mingling_ci/` | CI crate built on the Mingling framework, invoked via `cargo ci` | -| **CI orchestration** | `.run/src/bin/ci.py` | Full pipeline script (lock → checks → refresh → unlock) | +| Category | Path/Name | Description | +| --------------------------- | -------------------- | ----------------------------------------------------------------------- | +| **Entry crate** | `mingling/` | Project entry point | +| **Core library** | `mingling_core/` | Imported as an external dependency | +| **Macro library** | `mingling_macros/` | Imported as an external dependency | +| **Mingling Pathfinder** | `mingling_pathf/` | Build-time module path resolution for types | +| **Mingling Picker2** | `arg_picker/` | Mingling Arguments Parser | +| **Mingling Picker2 Macros** | `arg_picker_macros/` | Mingling Arguments Parser Macros | +| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` | +| **Examples** | `examples/` | To add expected output tests, add a `test.toml` in the example's dir | +| **Documents** | `docs/` | All documents | +| **Dev Documents** | `docs/dev/` | Internal documents | +| **Resources** | `docs/res/` | All resources | +| **CI system** | `mingling_ci/` | CI crate built on the Mingling framework, invoked via `cargo ci` | +| **CI orchestration** | `.run/src/bin/ci.py` | Full pipeline script (lock → checks → refresh → unlock) | | **Development tools** | `.run/src/bin` | Contains scripts and Rust tools (`deploy-api-docs`, `install-mling`, …) | -| **CI configs** | `.config/` | `ci-ignored-dirs.txt`, `verified-docs.toml`, `docs-lang.txt` | -| **Temporary files** | `.temp/` | Ignored by `.gitignore` | +| **CI configs** | `.config/` | `ci-ignored-dirs.txt`, `verified-docs.toml`, `docs-lang.txt` | +| **Temporary files** | `.temp/` | Ignored by `.gitignore` | ## 2. How to Contribute @@ -190,3 +190,7 @@ Mingling uses the **MIT + Apache 2.0** dual license. For details, please see: - [LICENSE-MIT](LICENSE-MIT) - [LICENSE-APACHE](LICENSE-APACHE) + +# Contributors + +<img src="https://contrib.rocks/image?repo=mingling-rs/mingling" /> @@ -12,22 +12,22 @@ <p align="center"> Macro magician in your CLI. </p> + <p align="center"> - <img src="https://img.shields.io/github/license/mingling-rs/mingling"> - <img src="https://img.shields.io/github/stars/mingling-rs/mingling?style=flat"> - <img src="https://img.shields.io/crates/size/mingling"> - <img src="https://img.shields.io/crates/v/mingling?style=flat"> - <img src="https://img.shields.io/docsrs/mingling?style=flat"> - <img src="https://img.shields.io/github/actions/workflow/status/mingling-rs/mingling/ci.yml"> + <img alt="License" src="https://img.shields.io/github/license/mingling-rs/mingling?style=for-the-badge&color=yellow"> + <img alt="GitHub stars" src="https://img.shields.io/github/stars/mingling-rs/mingling?style=for-the-badge&color=yellow"> + <img alt="Crate size" src="https://img.shields.io/crates/size/mingling?style=for-the-badge"> + <img alt="Crates.io version" src="https://img.shields.io/crates/v/mingling?style=for-the-badge"> + <img alt="CI" src="https://img.shields.io/github/actions/workflow/status/mingling-rs/mingling/ci.yml?style=for-the-badge"> </p> ## What is Mingling? [`Mingling`](https://github.com/mingling-rs/mingling) is a **state-driven and data-driven** CLI workflow orchestration framework built in Rust. -💡 Its name comes from the Chinese pinyin **"Mìng Lìng"**, which means **"command"**. +Its name comes from the Chinese pinyin **"Mìng Lìng"**, which means **"command"**. -## ⚠WARNING +## WARNING Mingling is currently usable at a basic level, but it is still under active development, so many APIs are not yet mature. Any changes to the public API will be documented in detail in the [Changelog](https://github.com/mingling-rs/mingling/blob/main/CHANGELOG.md). @@ -35,69 +35,104 @@ Additionally, the project is currently developed by me alone ([Weicao-CatilGrass ## About Mingling's Design -Mingling abstracts the behavior of a program's lifecycle into three phases: **Dispatch**, **Execution**, and **Rendering**. Each phase is connected by types — the output of the current phase becomes the input of the next phase. For example: +Mingling aims to organize and manage the architectural concerns of command-line programs through reasonable abstractions: it breaks a program down into the following concepts: + +| Concept | Description | +| -------------: | :--------------------------------------------------------------- | +| **Command** | A combination of **Dispatcher** and **Chain** | +| **Dispatcher** | Maps user input to entry types | +| **Chain** | Provides behavioral logic for any type and returns the next type | +| **Renderer** | Renders any type into output-ready text | +| **Resource** | Provides global **data** for the program | +| **Hook** | Provides global **behavior** for the program | + +## Example + +Below is a typical Mingling program that demonstrates how to implement a simple adder: ```rust -dispatcher!("current", EntryCurrent); +// Features: ["mini"] #[derive(Grouped)] -pub struct StateNext; - -#[chain] -fn handle_current(_: EntryCurrent) -> StateNext { - // 1. The first phase outputs the StateNext value - StateNext // ^^^^^^^^^ -} // | - // | - // 2. The second phase takes StateNext as input -#[chain] // | -fn handle_state_next(_: StateNext) { - todo!() +struct ResultNumber(f32); + +#[command] +fn sum(args: Entry) -> ResultNumber { + let (a, b) = args + .pick(&arg![f32]) + .pick(&arg![f32]) + .unwrap(); + ResultNumber(a + b) +} + +#[renderer] +fn render_number(n: ResultNumber) -> String { + format!("Result is {}", n.0) } ``` -See? `handle_current` and `handle_state_next` have no direct connection! +Output: -They are bridged by `StateNext` and automatically linked by the framework. +```bash +~# my-cli sum 5 10 +Result is 15 +``` -You can use this approach to separate computation from result rendering, like this: +If we add full error handling, it would look like this: ```rust -// Features: ["picker"] -use mingling::macros::buffer; -use mingling::prelude::*; +// Features: ["mini"] -dispatcher!("calc", EntryCalculate); +use mingling::macros::routeify; +use mingling::setup::ExitCodeSetup; +use mingling::res::ResExitCode; -#[derive(Grouped, Wrap)] -pub struct StateSumNumbers(Vec<i32>); +fn main() { + let mut program = ThisProgram::new(); + program.with_setup(ExitCodeSetup); + program.exec_and_exit(); +} -#[derive(Grouped, Wrap)] -pub struct ResultNumber(i32); +#[derive(Grouped)] +struct ResultNumber(f32); -// Entry: parse arguments and pass state to the calculation step -#[chain] -fn handle_calc(args: EntryCalculate) -> StateSumNumbers { - let numbers = args.pick(&arg![Vec<i32>]).unwrap(); - StateSumNumbers(numbers) +#[derive(Grouped)] +struct ErrorNoNumber; + +#[command(routeify)] +fn sum(args: Entry) -> Next { + let (a, b) = args + .pick_or_route(&arg![f32], || ErrorNoNumber.into()) + .pick_or_route(&arg![f32], || ErrorNoNumber.into()) + .to_result()?; + ResultNumber(a + b).into() } -// Calculate: pass the result to the rendering step -#[chain] -fn handle_state_sum_numbers(sum: StateSumNumbers) -> ResultNumber { - let numbers = sum.0; - let total: i32 = numbers.iter().sum(); - ResultNumber(total) +#[renderer] +fn render_error_no_num(n: ErrorNoNumber, ec: &mut ResExitCode) -> String { + ec.exit_code = 1; + format!("Error: No number provided.") } -// Renderer: return the render result and let the framework handle output -#[renderer(buffer)] -fn render_number(number: ResultNumber) { - r_println!("Number: {}", *number); +#[renderer] +fn render_number(n: ResultNumber) -> String { + format!("Result is {}", n.0) } ``` -Although this may make your program slightly more verbose, each step is a **pure function**, making it extremely easy to test! +Output: + +```bash +~# my-cli sum 5 10 +Result is 15 + +~# my-cli sum +Error: No number provided. << 1 +``` + +See! By assembling `ExitCodeSetup` and modifying `ResExitCode`, we **explicitly** mark the side effect of changing the exit code on the `render_error_no_num` function. This is exactly the problem Mingling aims to solve: **separating concerns by separating side effects through architecture**. + +Of course, by combining the concepts above, you can elegantly separate the side effects of your program into independent resources, keeping your execution functions pure. ## Getting Started @@ -123,31 +158,6 @@ To learn more, check out [Writing with Mingling](https://github.com/mingling-rs/ > [!Note] > You can also use the `mling` scaffolding tool to build, check, and manage your project [Download](https://mingling-rs.github.io/mingling/dist) | [About](https://github.com/mingling-rs/mingling/tree/main/mingling_cli) -## Roadmap - -- [x] Milestone.1 "MVP" 🎉 - - [x] [[0.1.4](https://docs.rs/mingling/0.1.4/mingling/)] [`core`] [`structural_renderer`] **Mingling** can render data into serializable formats via `--json` and `--yaml` flags - - [x] [[0.1.5](https://docs.rs/mingling/0.1.5/mingling/)] [`core`] [`comp`] **Mingling** can dynamically invoke itself to provide completions for shells like `bash`, `zsh`, `fish`, and `pwsh` - - [x] [[0.1.6](https://docs.rs/mingling/0.1.6/mingling/)] [`core`] [`comp`] **Mingling** can gather more context for smarter completions - - [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`clap`] Provides a **Clap** compatibility layer, allowing **Mingling** to reuse its powerful parsing capabilities - - [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`core`] **Mingling** can intercept `-h` or `--help` flags to display custom help text for each subcommand - - [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`mling`] Provides a basic scaffolding tool (`mling`) for rapid development and debugging - - [x] [[0.1.8](https://docs.rs/mingling/0.1.8/mingling/)] [`core`] [`dispatch_tree`] Converts the subcommand list into a prefix tree to improve command matching speed - - [x] [[0.1.9](https://docs.rs/mingling/0.1.9/mingling/)] [`core`] [`dev_toolkits`] Provides debugging interfaces for developers to capture invocation information when issues arise (`InvokeStackDisplay`) (indirectly implemented via `ProgramHook`) - - [x] [[0.1.9](https://docs.rs/mingling/0.1.9/mingling/)] [`core`] [`repl`] Provides REPL capability (`program.exec_repl();`) - - [x] [[0.2.0](https://docs.rs/mingling/0.2.0/mingling/)] Complete documentation, tests, and examples -- [ ] Milestone.2 "More Comfortable Dev and User Experience" - - [ ] [`mling` / `mingling-cli`] - - [x] **Mingling** Linter - - [x] **Mingling** Project Generator - - [x] **Mingling** Program Installer & Manager (For development) - - [ ] Helpdoc Editor - - [x] [`picker`] A more efficient and intelligent argument parser - - [x] [`macros`] ~~Remove r_print! / r_println! macros~~ (see below) - - [x] [`macros`] Make implicit modifications to functions explicit -- [ ] Milestone.3 "Unplanned" - - [ ] ... - ## Unplanned Features While Mingling has several common CLI features that are **NOT PLANNED** to be directly included in the framework. @@ -158,12 +168,6 @@ This is because the Rust ecosystem already has excellent and mature crates to ha - **Progress Bars**: To display progress indicators, the [`indicatif`](https://crates.io/crates/indicatif) crate is the standard choice. - **TUI**: To build full-screen interactive terminal applications, it is recommended to use a framework like [`ratatui`](https://crates.io/crates/ratatui) (formerly `tui-rs`). -## License - -This project is licensed under the MIT License. - -See [LICENSE-MIT](LICENSE-MIT) or [LICENSE-APACHE](LICENSE-APACHE) file for details. - ## Learn More **To learn more, check out the following links:** @@ -176,3 +180,12 @@ See [LICENSE-MIT](LICENSE-MIT) or [LICENSE-APACHE](LICENSE-APACHE) file for deta - 📖 API Doc - [docs.rs](https://docs.rs/mingling/latest/mingling/) | [latest](https://mingling-rs.github.io/mingling/docs/api-docs/mingling/) - 📖 Coverage Test - [LLVM Coverage](https://mingling-rs.github.io/mingling/docs/cov-test/) - 📖 Dev Doc - [Github](https://mingling-rs.github.io/mingling/docs/dev/) + +- 📖 Contribution - [CONTRIBUTING.md](./CONTRIBUTING.md) +- 🗺 Roadmap - [ROADMAP.md](./ROADMAP.md) + +## License + +This project is licensed under the MIT License. + +See [LICENSE-MIT](LICENSE-MIT) or [LICENSE-APACHE](LICENSE-APACHE) file for details. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..ed84ea5 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,33 @@ +# Roadmap + +## Milestone.1 "MVP" 🎉 + +This milestone completes the minimum viable version of Mingling. It does not introduce [semver](https://semver.org/) semantics; instead, it reaches a usable state through rapid Breaking Patches. + +- [x] [[0.1.4](https://docs.rs/mingling/0.1.4/mingling/)] [`core`] [`structural_renderer`] **Mingling** can render data into serializable formats via `--json` and `--yaml` flags +- [x] [[0.1.5](https://docs.rs/mingling/0.1.5/mingling/)] [`core`] [`comp`] **Mingling** can dynamically invoke itself to provide completions for shells like `bash`, `zsh`, `fish`, and `pwsh` +- [x] [[0.1.6](https://docs.rs/mingling/0.1.6/mingling/)] [`core`] [`comp`] **Mingling** can gather more context for smarter completions +- [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`clap`] Provides a **Clap** compatibility layer, allowing **Mingling** to reuse its powerful parsing capabilities +- [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`core`] **Mingling** can intercept `-h` or `--help` flags to display custom help text for each subcommand +- [x] [[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)] [`mling`] Provides a basic scaffolding tool (`mling`) for rapid development and debugging +- [x] [[0.1.8](https://docs.rs/mingling/0.1.8/mingling/)] [`core`] [`dispatch_tree`] Converts the subcommand list into a prefix tree to improve command matching speed +- [x] [[0.1.9](https://docs.rs/mingling/0.1.9/mingling/)] [`core`] [`dev_toolkits`] Provides debugging interfaces for developers to capture invocation information when issues arise (`InvokeStackDisplay`) (indirectly implemented via `ProgramHook`) +- [x] [[0.1.9](https://docs.rs/mingling/0.1.9/mingling/)] [`core`] [`repl`] Provides REPL capability (`program.exec_repl();`) +- [x] [[0.2.0](https://docs.rs/mingling/0.2.0/mingling/)] Complete documentation, tests, and examples + +## Milestone.2 "More Comfortable Dev and User Experience" + +Starting from this milestone, Mingling will fully adhere to [semver](https://semver.org/) semantics, polishing the API and surrounding toolchain to ensure a comfortable and convenient command-line development experience. + +- [ ] [`mling` / `mingling-cli`] + - [x] **Mingling** Linter + - [x] **Mingling** Project Generator + - [x] **Mingling** Program Installer & Manager (For development) + - [ ] Helpdoc Editor +- [x] [`picker`] A more efficient and intelligent argument parser +- [x] [`macros`] ~~Remove r_print! / r_println! macros~~ (see below) +- [x] [`macros`] Make implicit modifications to functions explicit + +## Milestone.3 "Unplanned" + +- [ ] ... |
