From 81be96847833bd443ddb157cedb7939d8ffcc150 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 2 May 2026 01:38:36 +0800 Subject: Enforce `NextProcess` return type in chain functions and update examples --- mingling/src/example_docs.rs | 119 +++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 61 deletions(-) (limited to 'mingling/src') diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs index 81eb2ef..c23db8d 100644 --- a/mingling/src/example_docs.rs +++ b/mingling/src/example_docs.rs @@ -1,136 +1,133 @@ // Auto generated -/// `Mingling` Example - Async -/// -/// After enabling the `async` feature: -/// 1. The `chain!` macro will support using **async** functions, -/// 2. The `exec` function of `Program` will return a `Future` for you to use with an async runtime -/// -/// ## Enable Feature -/// Enable the `async` feature for mingling in `Cargo.toml` -/// ```toml -/// [dependencies] -/// mingling = { version = "...", features = ["async"] } -/// ``` +/// `Mingling` Example - Basic /// /// # How to Run /// ```bash -/// cargo run --manifest-path ./examples/example-async/Cargo.toml -- hello World +/// cargo run --manifest-path ./examples/example-basic/Cargo.toml -- hello World /// ``` /// /// Cargo.toml /// ```ignore /// [package] -/// name = "example-async" +/// name = "example-basic" /// version = "0.0.1" /// edition = "2024" /// /// [dependencies] -/// tokio = { version = "1", features = ["full"] } -/// mingling = { path = "../../mingling", features = ["async"] } +/// mingling = { path = "../../mingling" } /// ``` /// /// main.rs /// ```ignore /// use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; /// +/// // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry` /// dispatcher!("hello", HelloCommand => HelloEntry); /// -/// // Use Tokio async runtime -/// #[tokio::main] -/// async fn main() { +/// fn main() { +/// // Create program /// let mut program = ThisProgram::new(); +/// +/// // Add dispatcher `HelloCommand` /// program.with_dispatcher(HelloCommand); /// /// // Run program -/// program.exec().await; +/// program.exec(); /// } /// +/// // Register wrapper type `Hello`, setting inner to `String` /// pack!(Hello = String); /// -/// // You can freely use async / non-async functions to declare your Chain -/// +/// // Register chain to `ThisProgram`, handling logic from `HelloEntry` /// #[chain] -/// // fn parse_name(prev: HelloEntry) -> NextProcess { -/// async fn parse_name(prev: HelloEntry) -> mingling::ChainProcess { +/// fn parse_name(prev: HelloEntry) -> NextProcess { +/// // Extract string from `HelloEntry` as argument /// let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); +/// +/// // Build `Hello` type and route to renderer /// Hello::new(name).to_render() /// } /// -/// // For renderers, you can still only use synchronous functions +/// // Register renderer to `ThisProgram`, handling rendering of `Hello` /// #[renderer] /// fn render_hello_who(prev: Hello) { +/// // Print message /// r_println!("Hello, {}!", *prev); +/// +/// // Program ends here /// } /// +/// // Generate program, default is `ThisProgram` /// gen_program!(); /// ``` -pub mod example_async {} -/// `Mingling` Example - Basic +pub mod example_basic {} +/// `Mingling` Example - Async +/// +/// After enabling the `async` feature: +/// 1. The `chain!` macro will support using **async** functions, +/// 2. The `exec` function of `Program` will return a `Future` for you to use with an async runtime +/// +/// ## Enable Feature +/// Enable the `async` feature for mingling in `Cargo.toml` +/// ```toml +/// [dependencies] +/// mingling = { version = "...", features = ["async"] } +/// ``` /// /// # How to Run /// ```bash -/// cargo run --manifest-path ./examples/example-basic/Cargo.toml -- hello World +/// cargo run --manifest-path ./examples/example-async/Cargo.toml -- hello World /// ``` /// /// Cargo.toml /// ```ignore /// [package] -/// name = "example-basic" +/// name = "example-async" /// version = "0.0.1" /// edition = "2024" /// /// [dependencies] -/// mingling = { path = "../../mingling" } +/// tokio = { version = "1", features = ["full"] } +/// mingling = { path = "../../mingling", features = ["async"] } /// ``` /// /// main.rs /// ```ignore -/// use mingling::{ -/// ChainProcess, -/// macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, -/// }; +/// use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; /// -/// // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry` /// dispatcher!("hello", HelloCommand => HelloEntry); /// -/// fn main() { -/// // Create program +/// // Use Tokio async runtime +/// #[tokio::main] +/// async fn main() { /// let mut program = ThisProgram::new(); -/// -/// // Add dispatcher `HelloCommand` /// program.with_dispatcher(HelloCommand); /// /// // Run program -/// program.exec(); +/// program.exec().await; /// } /// -/// // Register wrapper type `Hello`, setting inner to `String` /// pack!(Hello = String); /// -/// // Register chain to `ThisProgram`, handling logic from `HelloEntry` +/// // You can freely use async / non-async functions to declare your Chain +/// /// #[chain] -/// fn parse_name(prev: HelloEntry) -> ChainProcess { -/// // Extract string from `HelloEntry` as argument +/// // fn parse_name(prev: HelloEntry) -> NextProcess { +/// async fn parse_name(prev: HelloEntry) -> NextProcess { /// let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); -/// -/// // Build `Hello` type and route to renderer /// Hello::new(name).to_render() /// } /// -/// // Register renderer to `ThisProgram`, handling rendering of `Hello` +/// // For renderers, you can still only use synchronous functions /// #[renderer] /// fn render_hello_who(prev: Hello) { -/// // Print message /// r_println!("Hello, {}!", *prev); -/// -/// // Program ends here /// } /// -/// // Generate program, default is `ThisProgram` /// gen_program!(); /// ``` -pub mod example_basic {} +pub mod example_async {} /// `Mingling` Example - Completion /// /// # How to Deploy @@ -171,7 +168,7 @@ pub mod example_basic {} /// main.rs /// ```ignore /// use mingling::{ -/// ChainProcess, EnumTag, Groupped, ShellContext, Suggest, +/// EnumTag, Groupped, ShellContext, Suggest, /// macros::{ /// chain, completion, dispatcher, gen_program, r_println, renderer, suggest, suggest_enum, /// }, @@ -242,9 +239,9 @@ pub mod example_basic {} /// impl PickableEnum for FruitType {} /// /// #[chain] -/// fn parse_fruit_info(prev: FruitEntry) -> ChainProcess { -/// let picker = Picker::<()>::from(prev.inner); -/// let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack_directly(); +/// fn parse_fruit_info(prev: FruitEntry) -> NextProcess { +/// let picker = Picker::from(prev.inner); +/// let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack(); /// let info = FruitInfo { /// name: fruit_name, /// fruit_type, @@ -325,7 +322,7 @@ pub mod example_completion {} /// main.rs /// ```ignore /// use mingling::{ -/// ChainProcess, Groupped, +/// Groupped, /// macros::{chain, dispatcher, gen_program, r_println, renderer}, /// parser::Picker, /// setup::GeneralRendererSetup, @@ -352,11 +349,11 @@ pub mod example_completion {} /// } /// /// #[chain] -/// fn parse_render(prev: RenderCommandEntry) -> ChainProcess { -/// let (name, age) = Picker::<()>::new(prev.inner) +/// fn parse_render(prev: RenderCommandEntry) -> NextProcess { +/// let (name, age) = Picker::new(prev.inner) /// .pick::(()) /// .pick::(()) -/// .unpack_directly(); +/// .unpack(); /// Info { name, age }.to_render() /// } /// @@ -419,7 +416,7 @@ pub mod example_general_renderer {} /// pack!(ParsedPickInput = (i32, String)); /// /// #[chain] -/// fn parse(prev: PickEntry) -> mingling::ChainProcess { +/// fn parse(prev: PickEntry) -> NextProcess { /// // Extract arguments from `PickEntry`'s inner and create a `Picker` /// let picker = Picker::new(prev.inner); /// let picked = picker -- cgit