diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-20 09:50:28 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-20 09:50:28 +0800 |
| commit | c385dcf15930d2754b68c2794986ad30fc65c141 (patch) | |
| tree | 2fed45ade07d96d195b9f9a35a1de0aeda11ee5e /docs/_zh_CN | |
| parent | 7b3a1d7fd9f60b91a7f9602374c081882d46facc (diff) | |
docs: migrate renderer examples to buffer macro and update docs
Update all documentation and code examples to use the new
`#[renderer(buffer)]`
pattern with `r_println!` instead of manually constructing
`RenderResult`
with `writeln!`.
Diffstat (limited to 'docs/_zh_CN')
| -rw-r--r-- | docs/_zh_CN/pages/10-help.md | 26 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/11-resource-system.md | 18 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/14-testing.md | 2 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/4-render-result.md | 49 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/5-multiple-commands.md | 17 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/6-argument-parse-picker.md | 45 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/7-argument-parse-clap.md | 30 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/9-error-handling.md | 34 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/advanced/2-structural-renderer.md | 18 | ||||
| -rw-r--r-- | docs/_zh_CN/pages/other/naming_rule.md | 17 |
10 files changed, 119 insertions, 137 deletions
diff --git a/docs/_zh_CN/pages/10-help.md b/docs/_zh_CN/pages/10-help.md index 8cee2aa..1c4e410 100644 --- a/docs/_zh_CN/pages/10-help.md +++ b/docs/_zh_CN/pages/10-help.md @@ -13,18 +13,17 @@ Mingling 里用 `#[help]` 宏给命令添加帮助文本。 ```rust @@@use mingling::macros::help; +@@@use mingling::macros::buffer; @@@dispatcher!("greet", CMDGreet => EntryGreet); -#[help] -fn help_greet(_entry: EntryGreet) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Usage: greet [name]").ok(); - writeln!(r, "Say hello to someone.").ok(); - r +#[help(buffer)] +fn help_greet(_entry: EntryGreet) { + r_println!("Usage: greet [name]"); + r_println!("Say hello to someone."); } ``` > [!NOTE] -> 帮助函数同样通过 `writeln!` 向 `RenderResult` 写入内容,因为 `#[help]` 遵循渲染管线 —— 它是由 `--help` 标志提前触发的短路渲染,而不是管线之外的逻辑。 +> 帮助函数同样通过 `r_println!` 向 `RenderResult` 写入内容,因为 `#[help]` 遵循渲染管线 —— 它是由 `--help` 标志提前触发的短路渲染,而不是管线之外的逻辑。 ## 全局帮助 @@ -32,14 +31,13 @@ fn help_greet(_entry: EntryGreet) -> RenderResult { ```rust @@@use mingling::macros::help; +@@@use mingling::macros::buffer; // 用户直接输入 --help 时触发 -#[help] -fn help_root(entry: ErrorDispatcherNotFound) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Usage: my-cli <command>").ok(); - writeln!(r, "Commands:").ok(); - writeln!(r, " greet Say hello").ok(); - r +#[help(buffer)] +fn help_root(entry: ErrorDispatcherNotFound) { + r_println!("Usage: my-cli <command>"); + r_println!("Commands:"); + r_println!(" greet Say hello"); } ``` diff --git a/docs/_zh_CN/pages/11-resource-system.md b/docs/_zh_CN/pages/11-resource-system.md index a8aab4d..b127a3a 100644 --- a/docs/_zh_CN/pages/11-resource-system.md +++ b/docs/_zh_CN/pages/11-resource-system.md @@ -27,6 +27,7 @@ fn main() { 在 Chain 或 Renderer 中,只需在参数列表里声明你要的资源: ```rust +@@@use mingling::macros::buffer; @@@#[derive(Default, Clone)] @@@struct ResCurrentDir(String); @@@dispatcher!("pwd", CMDPrintWorkingDir => EntryPrintWorkingDir); @@ -37,11 +38,9 @@ fn handle_pwd(_args: EntryPrintWorkingDir, cwd: &ResCurrentDir) -> Next { ResultPath::new(cwd.0.clone()).to_render() } -#[renderer] -fn render_path(result: ResultPath) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "{}", *result).ok(); - r +#[renderer(buffer)] +fn render_path(result: ResultPath) { + r_println!("{}", *result); } ``` @@ -50,6 +49,7 @@ fn render_path(result: ResultPath) -> RenderResult { 用 `&mut T` 注入可修改资源: ```rust +@@@use mingling::macros::buffer; @@@#[derive(Default, Clone)] @@@struct ResVisitCount(u32); @@@dispatcher!("visit", CMDVisit => EntryVisit); @@ -60,11 +60,9 @@ fn handle_visit(_args: EntryVisit, counter: &mut ResVisitCount) -> Next { ResultDone::default().into() } -#[renderer] -fn render_done(_done: ResultDone, counter: &ResVisitCount) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "visit count is : {}", counter.0).ok(); - r +#[renderer(buffer)] +fn render_done(_done: ResultDone, counter: &ResVisitCount) { + r_println!("visit count is : {}", counter.0); } ``` diff --git a/docs/_zh_CN/pages/14-testing.md b/docs/_zh_CN/pages/14-testing.md index 621d43e..031be59 100644 --- a/docs/_zh_CN/pages/14-testing.md +++ b/docs/_zh_CN/pages/14-testing.md @@ -16,7 +16,7 @@ Renderer 是最容易测试的——调用函数,断言返回结果: #[renderer] fn render_greet(result: ResultName) -> RenderResult { let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *result).ok(); + r_println!(r, "Hello, {}!", *result); r } diff --git a/docs/_zh_CN/pages/4-render-result.md b/docs/_zh_CN/pages/4-render-result.md index 81c5102..8b29fca 100644 --- a/docs/_zh_CN/pages/4-render-result.md +++ b/docs/_zh_CN/pages/4-render-result.md @@ -10,18 +10,31 @@ 跟 `#[chain]` 类似,`#[renderer]` 用于标记一个输出函数: ```rust -use std::io::Write; +@@@use mingling::macros::buffer; +@@@pack!(ResultName = String); +#[renderer(buffer)] +fn render_name(name: ResultName) { + r_println!("Hello, {}!", *name); +} +``` + +Renderer 接收 Chain 产出的结果,然后返回一个 `RenderResult`。在函数内部,创建 `RenderResult`,用 `r_print!` / `r_println!` 写入内容,最后返回它。 + +## `buffer` 拓展 + +若您觉得显式创建并返回 `RenderResult` 过于繁琐,可以使用 `#[renderer(buffer)]` 在原始函数内植入一个缓冲区。 + +```rust +use mingling::macros::buffer; @@@pack!(ResultName = String); -#[renderer] -fn render_name(name: ResultName) -> RenderResult { - let mut result = RenderResult::new(); - writeln!(result, "Hello, {}!", *name).ok(); - result +#[renderer(buffer)] +fn render_name(name: ResultName) { + r_println!("Hello, {}!", *name); } ``` -Renderer 接收 Chain 产出的结果,然后返回一个 `RenderResult`。在函数内部,创建 `RenderResult`,用 `write!` / `writeln!`(来自 [`std::io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html))写入内容,最后返回它。 +这样,你的 renderer 函数就获得了更简洁的语法,但也引入了一个隐含机制:它会向函数内注入一个名为 `__render_result_buffer` 的可变 `RenderResult`。当 `r_print!` 宏没有显式指定 `RenderResult` 时,它便会按照约定向该缓冲区追加输出。 ## `RenderResult` 类型 @@ -36,7 +49,7 @@ Renderer 接收 Chain 产出的结果,然后返回一个 `RenderResult`。在 把三篇教程的内容合在一起,你的第一个 Mingling 程序就完整了: ```rust -use std::io::Write; +use mingling::macros::buffer; // 1. 用 Dispatcher 声明命令 dispatcher!("greet", CMDGreet => EntryGreet); @@ -55,11 +68,9 @@ fn handle_greet(args: EntryGreet) -> Next { } // 4. 用 Renderer 输出结果 -#[renderer] -fn render_name(name: ResultName) -> RenderResult { - let mut result = RenderResult::new(); - writeln!(result, "Hello, {}!", *name).ok(); - result +#[renderer(buffer)] +fn render_name(name: ResultName) { + r_println!("Hello, {}!", *name); } // 5. 在 main 函数内装配程序并运行 @@ -108,17 +119,15 @@ cargo run -- great `gen_program!()` 自动生成了一个 `ErrorDispatcherNotFound` 类型,包裹 `Vec<String>`——它存的是用户输入的那些没匹配到的命令。你只需要给它写一个 Renderer: ```rust -use std::io::Write; +use mingling::macros::buffer; -#[renderer] -fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) -> RenderResult { - let mut result = RenderResult::new(); +#[renderer(buffer)] +fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) { if err.inner.is_empty() { - writeln!(result, "Unknown command").ok(); + r_println!("Unknown command"); } else { - writeln!(result, "Command not found: \"{}\"", err.inner.join(" ")).ok(); + r_println!("Command not found: \"{}\"", err.inner.join(" ")); } - result } ``` diff --git a/docs/_zh_CN/pages/5-multiple-commands.md b/docs/_zh_CN/pages/5-multiple-commands.md index 38ce2cf..ff6596d 100644 --- a/docs/_zh_CN/pages/5-multiple-commands.md +++ b/docs/_zh_CN/pages/5-multiple-commands.md @@ -10,6 +10,7 @@ 继续在同一个项目里操作: ```rust +@@@use mingling::macros::buffer; // 声明两个命令 dispatcher!("greet", CMDGreet => EntryGreet); dispatcher!("add", CMDAdd => EntryAdd); @@ -29,18 +30,14 @@ fn handle_add(args: EntryAdd) -> Next { ResultSum::new(sum).into() } -#[renderer] -fn render_greet(result: ResultGreeting) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *result).ok(); - r +#[renderer(buffer)] +fn render_greet(result: ResultGreeting) { + r_println!("Hello, {}!", *result); } -#[renderer] -fn render_sum(result: ResultSum) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Sum: {}", *result).ok(); - r +#[renderer(buffer)] +fn render_sum(result: ResultSum) { + r_println!("Sum: {}", *result); } fn main() { diff --git a/docs/_zh_CN/pages/6-argument-parse-picker.md b/docs/_zh_CN/pages/6-argument-parse-picker.md index 4bf162c..f0609ed 100644 --- a/docs/_zh_CN/pages/6-argument-parse-picker.md +++ b/docs/_zh_CN/pages/6-argument-parse-picker.md @@ -139,6 +139,7 @@ fn handle_test_entry(prev: EntryTest) -> Next { ```rust // Features: ["parser", "extra_macros"] +@@@use mingling::macros::buffer; @@@use mingling::macros::route; @@@dispatcher!("greet", CMDGreet => EntryGreet); @@@pack!(ResultName = String); @@ -155,11 +156,9 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { ResultName::new(name).into() } -#[renderer] -fn render_greet(result: ResultName) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *result).ok(); - r +#[renderer(buffer)] +fn render_greet(result: ResultName) { + r_println!("Hello, {}!", *result); } ``` @@ -225,6 +224,7 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { ```rust // Features: ["parser", "extra_macros"] +@@@use mingling::macros::buffer; @@@use mingling::macros::route; @@@dispatcher!("greet", CMDGreet => EntryGreet); @@@pack!(ResultName = String); @@ -247,19 +247,15 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { ResultName::new(name).into() } -#[renderer] -fn render_name_too_long(prev: ErrorNameTooLong) -> RenderResult { - let mut r = RenderResult::new(); +#[renderer(buffer)] +fn render_name_too_long(prev: ErrorNameTooLong) { let len = *prev; - writeln!(r, "Error: name too long (length: {} > 32)", len).ok(); - r + r_println!("Error: name too long (length: {} > 32)", len); } -#[renderer] -fn render_name(prev: ResultName) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *prev).ok(); - r +#[renderer(buffer)] +fn render_name(prev: ResultName) { + r_println!("Hello, {}!", *prev); } ``` @@ -314,6 +310,7 @@ fn parse_size() { ```rust // Features: ["parser"] +@@@use mingling::macros::buffer; @@@use mingling::parser::{Pickable, Argument}; @@@use mingling::Flag; #[derive(Default, Clone)] @@ -341,11 +338,9 @@ fn handle_connect_entry(prev: EntryConnect) -> Next { ResultConnected::new(address).into() } -#[renderer] -fn render_connected(addr: ResultConnected) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Connected: IP: {} PORT: {}", addr.ip, addr.port).ok(); - r +#[renderer(buffer)] +fn render_connected(addr: ResultConnected) { + r_println!("Connected: IP: {} PORT: {}", addr.ip, addr.port); } ``` @@ -362,6 +357,7 @@ Connected: IP: 127.0.0.1 PORT: 8080 ```rust // Features: ["parser"] +@@@use mingling::macros::buffer; @@@use mingling::parser::PickableEnum; @@@use mingling::EnumTag; #[derive(Debug, Default, EnumTag)] @@ -382,11 +378,9 @@ fn handle_eat_entry(prev: EntryEat) -> Next { ResultFruit::new(fruit).into() } -#[renderer] -fn render_fruit(prev: ResultFruit) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Picked fruit: {:?}", *prev).ok(); - r +#[renderer(buffer)] +fn render_fruit(prev: ResultFruit) { + r_println!("Picked fruit: {:?}", *prev); } ``` @@ -395,3 +389,4 @@ fn render_fruit(prev: ResultFruit) -> RenderResult { <p align="center" style="font-size: 0.85em; color: gray;"> Written by @Weicao-CatilGrass </p> +```` diff --git a/docs/_zh_CN/pages/7-argument-parse-clap.md b/docs/_zh_CN/pages/7-argument-parse-clap.md index 21f886c..fda93f3 100644 --- a/docs/_zh_CN/pages/7-argument-parse-clap.md +++ b/docs/_zh_CN/pages/7-argument-parse-clap.md @@ -25,6 +25,7 @@ features = ["derive", "color"] // Dependencies: // clap = "4" @@@ use mingling::macros::dispatcher_clap; +@@@ use mingling::macros::buffer; #[derive(Default, clap::Parser, Grouped)] #[dispatcher_clap("greet", CMDGreet, help = true, error = ErrorGreetParsed)] pub struct EntryGreet { @@ -34,23 +35,19 @@ pub struct EntryGreet { repeat: i32, } -#[renderer] -fn render_greet(greet: EntryGreet) -> RenderResult { - let mut r = RenderResult::new(); +#[renderer(buffer)] +fn render_greet(greet: EntryGreet) { let count = greet.repeat.max(0) as usize; - write!(r, "Hello, ").ok(); + r_print!("Hello, "); for _ in 0..count { - write!(r, "{} ", greet.name).ok(); + r_print!("{} ", greet.name); } - writeln!(r, "!").ok(); - r + r_println!("!"); } -#[renderer] -fn render_greet_parse_failed(err: ErrorGreetParsed) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "{}", *err).ok(); - r +#[renderer(buffer)] +fn render_greet_parse_failed(err: ErrorGreetParsed) { + r_println!("{}", *err); } ``` @@ -62,6 +59,7 @@ fn render_greet_parse_failed(err: ErrorGreetParsed) -> RenderResult { // Features: ["clap"] // Dependencies: // clap = "4" +@@@use mingling::macros::buffer; @@@use mingling::setup::BasicProgramSetup; @@@use mingling::macros::dispatcher_clap; @@@#[derive(Default, clap::Parser, Grouped)] @@ -69,11 +67,9 @@ fn render_greet_parse_failed(err: ErrorGreetParsed) -> RenderResult { @@@pub struct EntryGreet { @@@ name: String, @@@} -@@@#[renderer] -@@@fn render_greet(greet: EntryGreet) -> RenderResult { -@@@ let mut r = RenderResult::new(); -@@@ write!(r, "Hello, {}!", greet.name).ok(); -@@@ r +@@@#[renderer(buffer)] +@@@fn render_greet(greet: EntryGreet) { +@@@ r_println!("Hello, {}!", greet.name); @@@} fn main() { let mut program = ThisProgram::new(); diff --git a/docs/_zh_CN/pages/9-error-handling.md b/docs/_zh_CN/pages/9-error-handling.md index 07c82da..4ce61ab 100644 --- a/docs/_zh_CN/pages/9-error-handling.md +++ b/docs/_zh_CN/pages/9-error-handling.md @@ -38,23 +38,20 @@ fn handle_greet(args: EntryGreet) -> Next { 然后各自写 Renderer: ```rust +@@@use mingling::macros::buffer; @@@dispatcher!("greet", CMDGreet => EntryGreet); @@@pack!(ResultGreeting = String); @@@pack!(ErrorNameEmpty = String); @@@#[chain] fn handle_greet(args: EntryGreet) -> Next { ResultGreeting::new(args.inner.first().cloned().unwrap_or_default()).to_render() } -#[renderer] -fn render_greet(result: ResultGreeting) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *result).ok(); - r +#[renderer(buffer)] +fn render_greet(result: ResultGreeting) { + r_println!("Hello, {}!", *result); } -#[renderer] -fn render_error_name_empty(err: ErrorNameEmpty) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Error: {}", *err).ok(); - r +#[renderer(buffer)] +fn render_error_name_empty(err: ErrorNameEmpty) { + r_println!("Error: {}", *err); } ``` @@ -63,6 +60,7 @@ fn render_error_name_empty(err: ErrorNameEmpty) -> RenderResult { ## 完整的例子 ```rust +@@@use mingling::macros::buffer; dispatcher!("greet", CMDGreet => EntryGreet); pack!(ResultGreeting = String); @@ -78,18 +76,14 @@ fn handle_greet(args: EntryGreet) -> Next { } } -#[renderer] -fn render_greet(result: ResultGreeting) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Hello, {}!", *result).ok(); - r +#[renderer(buffer)] +fn render_greet(result: ResultGreeting) { + r_println!("Hello, {}!", *result); } -#[renderer] -fn render_error_name_empty(err: ErrorNameEmpty) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Error: {}", *err).ok(); - r +#[renderer(buffer)] +fn render_error_name_empty(err: ErrorNameEmpty) { + r_println!("Error: {}", *err); } fn main() { diff --git a/docs/_zh_CN/pages/advanced/2-structural-renderer.md b/docs/_zh_CN/pages/advanced/2-structural-renderer.md index 70bed79..a498dac 100644 --- a/docs/_zh_CN/pages/advanced/2-structural-renderer.md +++ b/docs/_zh_CN/pages/advanced/2-structural-renderer.md @@ -27,6 +27,7 @@ features = ["structural_renderer"] // Features: ["structural_renderer"] // Dependencies: // serde = "1" +@@@use mingling::macros::buffer; @@@use mingling::setup::StructuralRendererSetup; @@@dispatcher!("render", CMDRender => EntryRender); @@ -40,11 +41,9 @@ fn handle_render(args: EntryRender) -> Next { ResultInfo::new((name, age)).into() } -#[renderer] -fn render_info(r: ResultInfo) -> RenderResult { - let mut result = RenderResult::new(); - writeln!(result, "{:?}", *r).ok(); - result +#[renderer(buffer)] +fn render_info(r: ResultInfo) { + r_println!("{:?}", *r); } ``` @@ -68,6 +67,7 @@ fn render_info(r: ResultInfo) -> RenderResult { // Features: ["structural_renderer"] // Dependencies: // serde = "1" +@@@use mingling::macros::buffer; @@@use mingling::prelude::*; @@@use mingling::setup::StructuralRendererSetup; @@@use mingling::StructuralData; @@ -87,11 +87,9 @@ fn handle_render(args: EntryRender) -> Next { Info { name, age }.to_render() } -#[renderer] -fn render_info(info: Info) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "{} is {} years old", info.name, info.age).ok(); - r +#[renderer(buffer)] +fn render_info(info: Info) { + r_println!("{} is {} years old", info.name, info.age); } @@@ @@@fn main() { diff --git a/docs/_zh_CN/pages/other/naming_rule.md b/docs/_zh_CN/pages/other/naming_rule.md index c854ba1..6e65ee4 100644 --- a/docs/_zh_CN/pages/other/naming_rule.md +++ b/docs/_zh_CN/pages/other/naming_rule.md @@ -166,6 +166,7 @@ fn handle_remote_add(args: EntryRemoteAdd, cwd: &ResCurrentDir, db: &mut ResData ## 完整示例 ```rust +@@@use mingling::macros::buffer; @@@ #[derive(Default, Clone)] @@@ struct ResDatabase { } @@@ impl ResDatabase { fn has_remote(&self, remote: &String) -> bool { true } } @@ -192,19 +193,15 @@ fn handle_state_operation_remotes(state: StateOperationRemotes, db: &ResDatabase } // 结果渲染 -#[renderer] -fn render_remote_added(result: ResultRemoteAdded) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Remote added: {}", result.inner).ok(); - r +#[renderer(buffer)] +fn render_remote_added(result: ResultRemoteAdded) { + r_println!("Remote added: {}", result.inner); } // 错误渲染 -#[renderer] -fn render_error_repository_not_found(err: ErrorRepositoryNotFound) -> RenderResult { - let mut r = RenderResult::new(); - writeln!(r, "Error: remote '{}' not found", err.inner).ok(); - r +#[renderer(buffer)] +fn render_error_repository_not_found(err: ErrorRepositoryNotFound) { + r_println!("Error: remote '{}' not found", err.inner); } ``` |
