From 6f3158896977a60c7c886c0960c8f9c0f2f0b2d9 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 15 Apr 2026 13:22:06 +0800 Subject: Add documentation for Dispatcher, Chain, and Renderer --- docs/pages/2-basic/3-dispatcher.md | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'docs/pages/2-basic/3-dispatcher.md') diff --git a/docs/pages/2-basic/3-dispatcher.md b/docs/pages/2-basic/3-dispatcher.md index 643a752..d0858d2 100644 --- a/docs/pages/2-basic/3-dispatcher.md +++ b/docs/pages/2-basic/3-dispatcher.md @@ -5,8 +5,92 @@ --- +## Intro +`Dispatcher` is a core concept in **Mingling**, used to dispatch user-input arguments to corresponding types, which are then handled by [Chain](pages/2-basic/4-chain) or [Renderer](pages/2-basic/5-renderer). +To define a `Dispatcher`, it is recommended to use the `dispatcher!` macro provided by `mingling_macros`: + +```rust +// User input: your_bin hello +// Will access HelloCommand and +// dispatch arguments to HelloEntry +dispatcher!("hello", + HelloCommand => HelloEntry); + +// User input: your_bin sub foo +// Will access FooCommand and +// dispatch arguments to FooEntry +dispatcher!("sub.foo", + FooCommand => FooEntry); + +// Same as above +dispatcher!("sub.bar", + BarCommand => BarEntry); +``` + +If you explicitly specify a name in the `gen_program!` macro, for example: + +```rust +gen_program!(MyProgram); +``` + +Then when using the `dispatcher!` macro, you must also explicitly specify the [Program](pages/2-basic/1-program): + +```rust +dispatcher!(MyProgram, "hello", + HelloCommand => HelloEntry); +``` + +**Tips:** Finally, add the `Dispatcher` you created to the [Program](pages/2-basic/1-program): + +```rust +#[tokio::main] +async fn main() { + let mut program = ThisProgram::new(); + program.with_dispatcher(HelloCommand); + program.with_dispatcher(SubFooCommand); + program.with_dispatcher(SubBarCommand); + program.exec().await; +} +``` + +## Manual Impl + +You can also manually implement the basic `Dispatcher` for more fine-grained control. However, compared to the procmacro, it is more cumbersome and cannot intelligently introduce certain traits based on the state of feature flags. + +```rust +// Define AddMemberEntry +// Use the `Groupped` derive to +// mark AddMemberEntry as a member of ThisProgram +#[derive(Debug, Groupped)] +pub struct AddMemberEntry { + // Define arguments to store user input + pub(crate) args: Vec, +} + +// Implement the Dispatcher trait +impl Dispatcher for AddMemberCommand { + // Return the node name of this Dispatcher + fn node(&self) -> Node { + node!("member.add") + } + + // When executing this Dispatcher, output AddMemberEntry + fn begin(&self, args: Vec) + -> ChainProcess + { + AnyOutput::new(AddMemberEntry { args }).route_chain() + } + + // Used to implement the clone trait for this Dispatcher + fn clone_dispatcher(&self) + -> Box> + { + Box::new(AddMemberCommand) + } +} +``` ## 💡 Next Page > **Basic Component** - Chain [Go](./pages/2-basic/4-chain) -- cgit