From 13408e79b940e9a33ca593ed30d1b20c54e01234 Mon Sep 17 00:00:00 2001
From: 魏曹先生 <1992414357@qq.com>
Date: Tue, 30 Jun 2026 18:05:05 +0800
Subject: feat(docs): add Chinese and English documentation for Mingling
tutorials
Add comprehensive documentation covering Declare a Dispatcher, Declare a
Chain, Rendering Results, Multi-Command Program, Argument Parsing with
Picker and Clap, Program Setup, Error Handling, Help Info, Resource
System, Exit Code Control, Hook System, Testing, Completion, Structural
Rendering, and Core Concepts
---
docs/pages/4-render-result.md | 142 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 142 insertions(+)
create mode 100644 docs/pages/4-render-result.md
(limited to 'docs/pages/4-render-result.md')
diff --git a/docs/pages/4-render-result.md b/docs/pages/4-render-result.md
new file mode 100644
index 0000000..5093a52
--- /dev/null
+++ b/docs/pages/4-render-result.md
@@ -0,0 +1,142 @@
+
Rendering Results
+
+ Use the #[renderer] macro to declare a renderer and output results
+
+
+Now that we've created a Dispatcher and a Chain, and produced a Result type via `pack!`, there's one final step: **presenting the result to the user**.
+
+## The `#[renderer]` Macro
+
+Similar to `#[chain]`, `#[renderer]` marks an output function:
+
+```rust
+pack!(ResultName = String);
+#[renderer]
+fn render_name(name: ResultName) {
+ r_println!("Hello, {}!", *name);
+}
+```
+
+A Renderer takes the result produced by a Chain and outputs it using `r_println!`. What's the difference between `r_println!` and the usual `println!`?
+
+## The `r_println!` and `r_print!` Macros
+
+`r_println!` and `r_print!` are printing macros provided by Mingling. They write content into a `RenderResult` instead of printing directly to the terminal. This offers several benefits:
+
+1. **RenderResult holds an exit code** — you can make the program exit with a specific code
+2. **Easier testing** — you can capture rendered output and make assertions
+3. **Post-processing** — you can capture results and apply uniform text post-processing
+
+> [!TIP]
+> For simple printing, you can think of it as a drop-in replacement for `println!`. Using `r_println!` instead of `println!` is a safe choice.
+
+## A Complete Runnable Program
+
+Putting the content of all three tutorials together, here's your first complete Mingling program:
+
+```rust
+// 1. Declare a command with Dispatcher
+dispatcher!("greet", CMDGreet => EntryGreet);
+
+// 2. Declare result data with pack!
+pack!(ResultName = String);
+
+// 3. Handle logic with Chain
+#[chain]
+fn handle_greet(args: EntryGreet) -> Next {
+ let name = args.inner
+ .first()
+ .cloned()
+ .unwrap_or_else(|| "World".to_string());
+ ResultName::new(name)
+}
+
+// 4. Output results with Renderer
+#[renderer]
+fn render_name(name: ResultName) {
+ r_println!("Hello, {}!", *name);
+}
+
+// 5. Assemble and run the program in main
+fn main() {
+ let mut program = ThisProgram::new();
+ program.with_dispatcher(CMDGreet);
+ program.exec_and_exit();
+}
+
+// 6. Generate the complete program with gen_program!
+gen_program!();
+```
+
+## Try It Out
+
+```bash
+~# cargo run -- greet Alice
+```
+
+```text
+Hello, Alice!
+```
+
+Try without arguments:
+
+```bash
+~# cargo run -- greet
+```
+
+```text
+Hello, World!
+```
+
+Try an unknown command:
+
+```bash
+cargo run -- great
+```
+
+```text
+# No output!
+```
+
+## Add a Fallback
+
+`gen_program!()` auto-generates an `ErrorDispatcherNotFound` type that wraps `Vec` — it holds the user's unmatched input. You just need to write a Renderer for it:
+
+```rust
+#[renderer]
+fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) {
+ if err.inner.is_empty() {
+ r_println!("Unknown command");
+ } else {
+ r_println!("Command not found: \"{}\"", err.inner.join(" "));
+ }
+}
+```
+
+With that added, try the unknown command again:
+
+```bash
+cargo run -- great
+```
+
+```text
+Command not found: "great"
+```
+
+## Congratulations
+
+You've completed your first full Mingling program! Here's a recap of what you've learned:
+
+| Concept | Macro/Function | In a Nutshell |
+| --------------- | ---------------- | ------------------------------------- |
+| Declare command | `dispatcher!` | Tell the program what users can input |
+| Handle logic | `#[chain]` | What to do with the arguments |
+| Output results | `#[renderer]` | How to present results to users |
+| Type wrapper | `pack!` | Give your data a meaningful name |
+| Program entry | `gen_program!()` | Auto-generate the pipeline wiring |
+
+In real projects you'll also use advanced features like resource injection, hooks, autocompletion, REPL, etc., but the core skeleton stays the same: **Dispatcher → Chain → Renderer**.
+
+
+ Written by @Weicao-CatilGrass
+
--
cgit