From 81635b93c597b10282cb14e0873f5e3d22395186 Mon Sep 17 00:00:00 2001
From: 魏曹先生 <1992414357@qq.com>
Date: Sat, 6 Jun 2026 23:16:51 +0800
Subject: Rename `ExitCode` to `ResExitCode` and `REPL` to `ResREPL`
---
docs/_zh_CN/_sidebar.md | 2 +
docs/_zh_CN/pages/other/naming_rule.md | 200 +++++++++++++++++++++++++++++++++
2 files changed, 202 insertions(+)
create mode 100644 docs/_zh_CN/pages/other/naming_rule.md
(limited to 'docs')
diff --git a/docs/_zh_CN/_sidebar.md b/docs/_zh_CN/_sidebar.md
index 8c854f9..5d0ebe1 100644
--- a/docs/_zh_CN/_sidebar.md
+++ b/docs/_zh_CN/_sidebar.md
@@ -1,3 +1,5 @@
- [Welcome!](README)
* [介绍](pages/1-intro)
* [初次上手!](pages/2-step1)
+* other
+ * [命名规范](pages/other/naming_rule)
diff --git a/docs/_zh_CN/pages/other/naming_rule.md b/docs/_zh_CN/pages/other/naming_rule.md
new file mode 100644
index 0000000..59dc9cd
--- /dev/null
+++ b/docs/_zh_CN/pages/other/naming_rule.md
@@ -0,0 +1,200 @@
+
命名规范
+
+ 让你的 Mingling 项目类型和函数名井井有条
+
+
+## 前言
+
+好的命名是大型 CLI 项目的基石。Mingling 的管线模式引入了几类新的类型(Entry、State、Result、Error、Resource),如果不加约束,项目里很快就会出现 `Data`、`Info`、`Context` 这类无法区分职责的名字。
+
+下面这套命名规范来自实践,已在生产项目中使用。它不是框架的强制规则,但建议跟随。
+
+## 类型命名
+
+### 资源
+
+资源是通过资源注入系统共享给所有 chain 和 renderer 的全局实例。
+
+```
+Res + 名称
+```
+
+| 示例 | 说明 |
+|------|------|
+| `ResCurrentDir` | 当前工作目录 |
+| `ResExitCode` | 进程退出码 |
+| `ResREPL` | REPL 状态 |
+
+### 构建
+
+构建是在程序启动时执行的初始化步骤,由 `with_setup` 注册。
+
+```
+名称 + Setup
+```
+
+| 示例 | 说明 |
+|------|------|
+| `BasicSetup` | 基础初始化(`--quiet`、`--help`、`--confirm`) |
+| `GeneralRendererSetup` | 通用渲染器初始化(`--json`、`--yaml` 等) |
+
+### 分发器
+
+分发器是命令的入口点,与 `Node` 名称一一对应。节点名用 `.` 分隔层级,分发器名用 `CMD` 前缀加 PascalCase。
+
+```
+CMD + 命令层级
+```
+
+| 节点 | 分发器 |
+|------|--------|
+| `greet` | `CMDGreet` |
+| `remote.add` | `CMDRemoteAdd` |
+| `remote.rm` | `CMDRemoteRemove` |
+
+即使节点是缩写,分发器的名称也要写全名。例如节点是 `remote.rm`,分发器是 `CMDRemoteRemove`,不是 `CMDRemoteRm`。
+
+### 入口
+
+入口是分发器创建的管线起始类型,包裹 `Vec`。
+
+```
+Entry + 命令层级
+```
+
+| 分发器 | 入口 |
+|--------|------|
+| `CMDGreet` | `EntryGreet` |
+| `CMDRemoteAdd` | `EntryRemoteAdd` |
+| `CMDRemoteRemove` | `EntryRemoteRemove` |
+
+### 状态
+
+状态是介于入口和结果之间的管线中间类型,代表经过部分处理后的数据。
+
+```
+State + 描述
+```
+
+| 示例 | 说明 |
+|------|------|
+| `StateOperationRemotes` | 正在操作远程仓库列表 |
+| `StateCheckRepository` | 正在检查仓库状态 |
+
+典型的管线链:`EntryRemoteAdd → StateOperationRemotes → StateCheckRepository`
+
+### 结果
+
+结果是管线中由 `to_render()` 发往 Renderer 的最终类型。
+
+```
+Result + 内容
+```
+
+| 示例 | 说明 |
+|------|------|
+| `ResultGreetSomeone` | 问候结果 |
+| `ResultFruitList` | 水果列表结果 |
+
+结果结构体期望被 Renderer 消费,内部结构应该为了渲染美观而设计。一般用 `#[derive(Groupped)]` 代替 `pack!()` 包装,以获得更灵活的字段控制。
+
+### 错误
+
+错误与结果不同。错误可以被 `to_chain()` 或 `to_render()` 发送,用于将执行路由到错误处理路径。
+
+```
+Error + 描述
+```
+
+| 示例 | 说明 |
+|------|------|
+| `ErrorRepositoryNotFound` | 仓库未找到 |
+
+`StateOperationRemotes → ErrorRepositoryNotFound`
+
+
+
+## 函数命名
+
+### Chain 函数
+
+| 处理类型 | 命名模式 | 示例 |
+|----------|----------|------|
+| Entry | `handle_` + entry 名(snake_case) | `handle_remote_add(prev: EntryRemoteAdd)` |
+| State | `handle_state_` + state 名(snake_case) | `handle_state_operation_remotes(prev: StateOperationRemotes)` |
+| Error | `handle_error_` + error 名(snake_case) | `handle_error_repository_not_found(prev: ErrorRepositoryNotFound)` |
+| Result | ❌ 不要为 Result 写 chain | — |
+
+### Renderer 函数
+
+| 处理类型 | 命名模式 | 示例 |
+|----------|----------|------|
+| Entry | `render_entry_` + entry 名 | `render_entry_remote_add(prev: EntryRemoteAdd)` |
+| State | ❌ 不要为 State 写 renderer | — |
+| Error | `render_error_` + error 名 | `render_error_repository_not_found(prev: ErrorRepositoryNotFound)` |
+| Result | `render_` + result 名 | `render_greet_someone(prev: ResultGreetSomeone)` |
+
+**原则**:不要为不会被用户看到或不需要独立渲染的中间类型写 renderer。
+
+---
+
+## 函数签名参数命名
+
+| 类型 | 推荐参数名 |
+|------|------------|
+| Entry | `args` |
+| State | `prev`(或具名如 `remotes`) |
+| Result | `result`(或具名如 `fruits`) |
+| Error | `err` |
+| 资源(不可变) | `cwd`、`db`、`config` 等 |
+| 资源(可变) | `counter`、`cache`、`session` 等 |
+
+```rust
+#[chain]
+fn handle_remote_add(args: EntryRemoteAdd, cwd: &ResCurrentDir, db: &mut ResDatabase) -> Next {
+ // args: 入口数据
+ // cwd: 注入的不可变资源
+ // db: 注入的可变资源
+}
+```
+
+---
+
+## 完整示例
+
+```rust
+// 分发器
+dispatcher!("remote.add", CMDRemoteAdd => EntryRemoteAdd);
+
+// 入口 → 状态
+#[chain]
+fn handle_remote_add(args: EntryRemoteAdd) -> Next {
+ StateOperationRemotes::new(...).to_chain()
+}
+
+// 状态 → 错误或结果
+#[chain]
+fn handle_state_operation_remotes(state: StateOperationRemotes, db: &ResDatabase) -> Next {
+ if db.has_remote(&state.name) {
+ ErrorRepositoryNotFound::new(...).to_render()
+ } else {
+ ResultRemoteAdded::new(...).to_render()
+ }
+}
+
+// 结果渲染
+#[renderer]
+fn render_remote_added(result: ResultRemoteAdded) {
+ r_println!("Remote added: {}", result.name);
+}
+
+// 错误渲染
+#[renderer]
+fn render_error_repository_not_found(err: ErrorRepositoryNotFound) {
+ r_println!("Error: remote '{}' not found", err.name);
+}
+```
+
+
+ Written by @Weicao-CatilGrass
+
--
cgit