diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-15 13:22:06 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-15 13:22:06 +0800 |
| commit | 6f3158896977a60c7c886c0960c8f9c0f2f0b2d9 (patch) | |
| tree | 7c5569c4874cf52d31942bbd148426cbb0b898a6 /docs/pages/2-basic/5-renderer.md | |
| parent | ac69d89702269436303f704f8b028dd5fe6578be (diff) | |
Add documentation for Dispatcher, Chain, and Renderer
Diffstat (limited to 'docs/pages/2-basic/5-renderer.md')
| -rw-r--r-- | docs/pages/2-basic/5-renderer.md | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/docs/pages/2-basic/5-renderer.md b/docs/pages/2-basic/5-renderer.md index f3e09de..1f566f2 100644 --- a/docs/pages/2-basic/5-renderer.md +++ b/docs/pages/2-basic/5-renderer.md @@ -4,3 +4,74 @@ </p> --- + +## Intro + +`Renderer` is similar to [Chain](pages/2-basic/4-chain) in that they both handle processing for a specific type. The difference is: [Chain](pages/2-basic/4-chain) transforms the type, while `Renderer` terminates the program and prints the information of that type to the terminal. + +A type can be processed by both [Chain](pages/2-basic/4-chain) and `Renderer`. If the type is `route_chain`ed, the system will search for a [Chain](pages/2-basic/4-chain) capable of handling that type. If none is found, it will automatically be routed to the `Renderer` to print the result of that type. + +The following example demonstrates how to handle rendering logic: + +```rust +dispatcher!("hello", + HelloCommand => HelloEntry); + +pack!(ParsedHello = String); + +// It's the Chain defined in the Dispatcher chapter +#[chain] +async fn parse_hello(prev: HelloEntry) -> NextProcess { + let args = &*prev; + let first = args + .first() + .cloned() + .unwrap_or_else(|| + "World".to_string() + ); + + // Distribute the type to the Renderer + ParsedHello::new(first).to_render() +} + +// Define the renderer to +// handle rendering of ParsedHello +#[renderer] +fn render_hello(prev: ParsedHello) { + // Use r_println or r_print to + // render the content of ParsedHello + r_println!("Hello, {}!", *prev) +} +``` + +> **About r_print** +> +> `r_print!` can only be used inside a `Renderer`. This is because after the `renderer!` macro expands, it injects `r: &mut RenderResult` into the context. +> +> And `r_print!` directly writes content to the value `r`. +> This means: if there is no `&mut RenderResult` named `r` in the context, `r_print!` cannot be used. + +## Manual Impl + +> ⚠️ WARNING +> +> The following content is not yet fully implemented; currently, only the `renderer!` macro is allowed for implementation. + +Similarly, you can also manually implement `Renderer`, + +but note that inside the `renderer!` macro, a `register_type!` macro is executed. This macro itself does not expand into any content; it is only used to inform the `gen_program` context that the type exists: + +```rust +struct RenderHello; +impl Renderer for RenderHello { + type Previous = ParsedHello; + fn render( + prev: Self::Previous, + r: &mut RenderResult + ) { + r_println!("Hello, {}!", *prev) + } +} + +register_type!(ParsedHello); +``` |
