From b9edeb9848e4a423e133fa2a13dede6d128d6f08 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 14 Apr 2026 22:47:08 +0800 Subject: Add documentation for Mingling CLI framework --- docs/pages/2-basic/2-setup.md | 169 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 docs/pages/2-basic/2-setup.md (limited to 'docs/pages/2-basic/2-setup.md') diff --git a/docs/pages/2-basic/2-setup.md b/docs/pages/2-basic/2-setup.md new file mode 100644 index 0000000..8dbdd76 --- /dev/null +++ b/docs/pages/2-basic/2-setup.md @@ -0,0 +1,169 @@ +

Setup

+

+ Mingling's Basic Components +

+ +--- + +## Usage + +`Setup` is used to organize and package the initialization process of a `Program`, making the project easier to manage. It is defined as follows: + +```rust +struct MySetup; +impl ProgramSetup + for MySetup +{ + fn setup( + &mut self, + program: &mut Program + ) { + // Your setup logic + } +} +``` + +For example: + +```rust +use std::{env::current_dir, path::PathBuf}; + +use mingling::{ + Program, + macros::{dispatcher, gen_program, renderer}, + setup::ProgramSetup, +}; + +// Global state +static OUTPUT_PATH: std::sync::OnceLock + = std::sync::OnceLock::new(); + +#[tokio::main] +async fn main() { + let mut program = ThisProgram::new(); + program.with_setup(MySetup); + program.exec().await; +} + +// Define two Dispatchers using `dispatcher!` +dispatcher!("member.add", + AddMemberCommand => AddMemberEntry); +dispatcher!("member.rm", + RemoveMemberCommand => RemoveMemberEntry); + +struct MySetup; +impl ProgramSetup for MySetup { + fn setup( + &mut self, program: &mut Program + ) { + // Register Dispatchers + program.with_dispatcher(AddMemberCommand); + program.with_dispatcher(RemoveMemberCommand); + + // Initialize global output once + OUTPUT_PATH.get_or_init(|| current_dir().unwrap()); + + // Pick the "--quiet" or "-q" flag + program.global_flag(["--quiet", "-q"], |p| { + // Disable render output + p.stdout_setting.render_output = false; + }); + + // Pick the "--output" or "-O" flag, write to output + program.global_argument(["--output", "-O"], |_, v| { + let _ = OUTPUT_PATH.set(PathBuf::from(v)); + }); + } +} + +// Define empty renderer types to give the two types type IDs + +#[renderer] +fn phantom_renderer_add_member( + _prev: AddMemberEntry +) {} + +#[renderer] +fn phantom_renderer_remove_member( + _prev: RemoveMemberEntry +) {} + +gen_program!(); +``` + +## Simplified Syntax + +If you find the above declaration method too **verbose**, you can use the `program_setup!` macro to simplify it. The format is: + +```rust +#[program_setup] +fn my_setup( + program: &mut Program +) { + // Your setup logic +} +``` + +For example: + +```rust +use std::{env::current_dir, path::PathBuf}; + +use mingling::{ + Program, + macros::{ + dispatcher, + gen_program, + program_setup, + renderer + }, +}; + +static OUTPUT_PATH: std::sync::OnceLock + = std::sync::OnceLock::new(); + +#[tokio::main] +async fn main() { + let mut program = ThisProgram::new(); + program.with_setup(MySetup); + program.exec().await; +} + +dispatcher!("member.add", + AddMemberCommand => AddMemberEntry); +dispatcher!("member.rm", + RemoveMemberCommand => RemoveMemberEntry); + +#[program_setup] +fn my_setup( + program: &mut Program +) { + program.with_dispatcher(AddMemberCommand); + program.with_dispatcher(RemoveMemberCommand); + + OUTPUT_PATH.get_or_init(|| current_dir().unwrap()); + + program.global_flag(["--quiet", "-q"], |p| { + p.stdout_setting.render_output = false; + }); + + program.global_argument(["--output", "-O"], |_, v| { + let _ = OUTPUT_PATH.set(PathBuf::from(v)); + }); +} + +#[renderer] +fn phantom_renderer_add_member( + _prev: AddMemberEntry +) {} + +#[renderer] +fn phantom_renderer_remove_member( + _prev: RemoveMemberEntry +) {} + +gen_program!(); +``` + +## 💡 Next Page +> **Basic Component** - Dispatcher [Go](./pages/2-basic/3-dispatcher) -- cgit