aboutsummaryrefslogtreecommitdiff
path: root/docs/_zh_CN/pages/2-implementing-fallbacks.md
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-05-03 00:26:43 +0800
committer魏曹先生 <1992414357@qq.com>2026-05-03 00:26:43 +0800
commit22f835690ad2680e910a54bfeccfa9f9a7ec7935 (patch)
tree0faa8f4fc2441396aa4802c15ecd7224e1352af0 /docs/_zh_CN/pages/2-implementing-fallbacks.md
parentca9d2c878b7222061c2c51d0f97c60b73d2cf565 (diff)
Restructure Chinese documentation into dedicated subdirectory
Diffstat (limited to 'docs/_zh_CN/pages/2-implementing-fallbacks.md')
-rw-r--r--docs/_zh_CN/pages/2-implementing-fallbacks.md139
1 files changed, 139 insertions, 0 deletions
diff --git a/docs/_zh_CN/pages/2-implementing-fallbacks.md b/docs/_zh_CN/pages/2-implementing-fallbacks.md
new file mode 100644
index 0000000..071a5d1
--- /dev/null
+++ b/docs/_zh_CN/pages/2-implementing-fallbacks.md
@@ -0,0 +1,139 @@
+<h1 align="center">实现回退机制</h1>
+<p align="center">
+ 使用回退机制处理程序的错误情况
+</p>
+
+## 书接上文
+
+ 在上文中,我们介绍了如何使用 **Mingling** 开发基本的命令行程序:你可以使用 `"greet"` 子命令输出 `"Hello, World!"`,也可以使用 `"greet Alice"` 输出 `"Hello, Alice!"`
+
+ 而当用户并未输入 `"greet"` 时呢?让我们键入命令尝试一下 ⌨️
+
+```bash
+~> your-bin hello
+~> your-bin hello Alice
+```
+
+ **它没有任何反应!** 👆
+
+ 让我来解释为什么:**Mingling** 不自作主张,无论发生什么它都不会输出内容到终端(除了 `unwind` 下的 `panic!`)
+
+ 这意味着,如果您需要在命令行程序出错时能够主动地做些什么,你就得显式声明。
+
+ 好在 **Mingling** 提供了较为方便的接口实现该功能:在 `gen_program!` 宏中,会生成两个 `FallBack` 类型
+
+|类型|发生时机|发生方式|
+|-|-|-|
+|RendererNotFound|调度无法找到的渲染器时|作为 `Chain` 调度|
+|DispatcherNotFound|输入命令但无法匹配分发器|作为 `Chain` 调度|
+
+### `DispatcherNotFound` 类型
+
+ 首先让我们关注 `DispatcherNotFound` 类型,它的产生方式如下:
+
+```rust
+// 1. 定义 `greet` 命令
+dispatcher!("greet", GreetCommand => GreetEntry);
+
+fn main() {
+ // ->> 用户输入 "hello Alice"
+ let mut program = ThisProgram::new();
+
+ // 2. 导入 `greet` 命令
+ program.with_dispatcher(GreetCommand);
+
+ // 3. 执行程序
+ program.exec();
+}
+
+// ...
+
+// 5. 接收 DispatcherNotFound 调度
+#[renderer]
+fn dispatcher_not_found(prev: DispatcherNotFound) {
+ // 6. 输出
+ r_println!(
+ "Cannot match any command! Current input: \"{}\"",
+ prev.join(" ")
+ );
+}
+
+// 4. 无法匹配到任何名为 `hello` 的分发器
+// 将用户参数原样分发到 DispatcherNotFound
+gen_program!();
+```
+
+ 上述程序的运行效果为:
+
+```bash
+~> omg hello
+Cannot match any command! Current input: "hello"
+
+~> omg hello Alice
+Cannot match any command! Current input: "hello Alice"
+```
+
+ 现在若用户输入了不匹配的命令,**Mingling** 将会输出对应的内容!
+
+## `RendererNotFound` 类型
+
+ `RendererNotFound` 有两种可能产生:
+
+ 1. 该类型被显式分发到了 `Renderer` (使用 `.to_render()` 函数),但是该类型未实现渲染器
+ 2. 该类型被分发到了 `Chain`,但是该类型未实现链,也未实现渲染器
+
+ 一般来说,`RendererNotFound` **不应该在业务逻辑中产生**:它被调度意味着您的类型需要被渲染但是并不能被渲染。您可以使用该类型来定位哪个类型缺失渲染器实现 ✏️
+
+```rust
+dispatcher!("greet", GreetCommand => GreetEntry);
+
+fn main() {
+ let mut program = ThisProgram::new();
+
+ program.with_dispatcher(GreetCommand);
+ program.exec();
+}
+
+pack!(ResultGreetSomeone = String);
+
+#[chain]
+fn handle_greet_entry(prev: GreetEntry) -> NextProcess {
+ let args = prev.inner;
+ let name = args.first().cloned().unwrap_or_else(|| "World".to_string());
+
+ ResultGreetSomeone::new(name)
+}
+
+// 让我们故意去除 `ResultGreetSomeone` 类型的渲染器实现
+// #[renderer]
+// fn render_greet_someone(prev: ResultGreetSomeone) {
+// r_println!("Hello, {}!", *prev);
+// }
+
+#[renderer]
+fn renderer_not_found(prev: RendererNotFound) {
+ if *prev == "DispatcherNotFound" {
+ return; // 排除 "DispatcherNotFound" 类型
+ }
+
+ // 当未找到渲染器时触发 `panic!`
+ panic!("Renderer \"{}\" not found!", *prev);
+}
+
+gen_program!();
+
+```
+
+ 上述程序的运行效果为:
+
+```bash
+~> your-bin greet Alice
+
+thread 'main' (90772) panicked at src/bin/your-bin.rs:30:5:
+Renderer "ResultGreetSomeone" not found!
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+```
+
+<p align="center" style="font-size: 0.85em; color: gray;">
+ Written by @Weicao-CatilGrass
+</p>