diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-06 20:19:43 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-06 20:19:43 +0800 |
| commit | 721b6f9f608977b938dbc9b847c9221370b5ee15 (patch) | |
| tree | 95483051d50d183357a097c41a678bad14c657c0 /examples | |
| parent | e68e1230d4157c32592900372699411c7151b4e5 (diff) | |
Add workspace configuration and examples
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/example-basic/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/example-basic/src/main.rs | 51 | ||||
| -rw-r--r-- | examples/example-general-renderer/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/example-general-renderer/src/main.rs | 71 | ||||
| -rw-r--r-- | examples/example-picker/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/example-picker/src/main.rs | 68 |
6 files changed, 217 insertions, 0 deletions
diff --git a/examples/example-basic/Cargo.toml b/examples/example-basic/Cargo.toml new file mode 100644 index 0000000..eb10e2a --- /dev/null +++ b/examples/example-basic/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "example-basic" +version.workspace = true +edition = "2024" + +[dependencies] +mingling.workspace = true +tokio.workspace = true +serde.workspace = true diff --git a/examples/example-basic/src/main.rs b/examples/example-basic/src/main.rs new file mode 100644 index 0000000..050bfd4 --- /dev/null +++ b/examples/example-basic/src/main.rs @@ -0,0 +1,51 @@ +//! `Mingling` Example - Basic +//! +//! # How to Run +//! ```bash +//! cargo run --manifest-path ./examples/example-basic/Cargo.toml -- hello World +//! ``` + +use mingling::{ + macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, + marker::NextProcess, +}; + +// Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry` +dispatcher!("hello", HelloCommand => HelloEntry); + +#[tokio::main] +async fn main() { + // Create program + let mut program = DefaultProgram::new(); + + // Add dispatcher `HelloCommand` + program.with_dispatcher(HelloCommand); + + // Run program + program.exec().await; +} + +// Register wrapper type `Hello`, setting inner to `String` +pack!(Hello = String); + +// Register chain to `DefaultProgram`, handling logic from `HelloEntry` +#[chain] +async 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() +} + +// Register renderer to `DefaultProgram`, handling rendering of `Hello` +#[renderer] +fn render_hello_who(prev: Hello) { + // Print message + r_println!("Hello, {}!", *prev); + + // Program ends here +} + +// Generate program, default is `DefaultProgram` +gen_program!(); diff --git a/examples/example-general-renderer/Cargo.toml b/examples/example-general-renderer/Cargo.toml new file mode 100644 index 0000000..22403a2 --- /dev/null +++ b/examples/example-general-renderer/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "example-general-renderer" +version.workspace = true +edition = "2024" + +[dependencies] +mingling.workspace = true +tokio.workspace = true +serde.workspace = true diff --git a/examples/example-general-renderer/src/main.rs b/examples/example-general-renderer/src/main.rs new file mode 100644 index 0000000..09fb09a --- /dev/null +++ b/examples/example-general-renderer/src/main.rs @@ -0,0 +1,71 @@ +//! `Mingling` Example - General Renderer +//! +//! ## Step1 - Enable Feature +//! Enable the `general_renderer` feature for mingling in `Cargo.toml` +//! ```toml +//! [dependencies] +//! mingling = { version = "...", features = ["general_renderer", "parser"] } +//! ``` +//! +//! ## Step2 - Add Dependencies +//! Add `serde` dependency to `Cargo.toml` for serialization support +//! ```toml +//! [dependencies] +//! serde = { version = "1", features = ["derive"] } +//! ``` +//! +//! ## Step3 - Write Code +//! Write the following content into `main.rs` +//! +//! ## Step3 - Build and Run +//! ```bash +//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22 +//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22 --json +//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22 --yaml +//! ``` + +use mingling::{ + AnyOutput, Groupped, + macros::{chain, dispatcher, gen_program, r_println, renderer}, + marker::NextProcess, + parser::Picker, + setup::GeneralRendererSetup, +}; +use serde::Serialize; + +dispatcher!("render", RenderCommand => RenderCommandEntry); + +#[tokio::main] +async fn main() { + let mut program = DefaultProgram::new(); + // Add `GeneralRendererSetup` to receive user input `--json` `--yaml` parameters + program.with_setup(GeneralRendererSetup); + program.with_dispatcher(RenderCommand); + program.exec().await; +} + +// Manually implement Info struct +#[derive(Serialize, Groupped)] +struct Info { + #[serde(rename = "member_name")] + name: String, + #[serde(rename = "member_age")] + age: i32, +} + +#[chain] +async fn parse_render(prev: RenderCommandEntry) -> NextProcess { + let (name, age) = Picker::<AnyOutput<DefaultProgram>>::new(prev.inner) + .pick::<String>(()) + .pick::<i32>(()) + .unpack_directly(); + AnyOutput::new(Info { name, age }).route_renderer() +} + +// Implement default renderer for when general_renderer is not specified +#[renderer] +fn render_info(prev: Info) { + r_println!("{} is {} years old", prev.name, prev.age); +} + +gen_program!(); diff --git a/examples/example-picker/Cargo.toml b/examples/example-picker/Cargo.toml new file mode 100644 index 0000000..2e514f7 --- /dev/null +++ b/examples/example-picker/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "example-picker" +version.workspace = true +edition = "2024" + +[dependencies] +mingling.workspace = true +tokio.workspace = true +serde.workspace = true diff --git a/examples/example-picker/src/main.rs b/examples/example-picker/src/main.rs new file mode 100644 index 0000000..24357a8 --- /dev/null +++ b/examples/example-picker/src/main.rs @@ -0,0 +1,68 @@ +//! `Mingling` Example - Picker +//! +//! ## Step1 - Enable Feature +//! Enable the `parser` feature for mingling in `Cargo.toml` +//! ```toml +//! [dependencies] +//! mingling = { version = "...", features = ["parser"] } +//! ``` +//! +//! ## Step2 - Write Code +//! Write the following content into `main.rs` +//! +//! ## Step3 - Build and Run +//! ```bash +//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick Bob +//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick Bob --age -15 +//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick --age 99 +//! ``` + +use mingling::{ + AnyOutput, + macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, + marker::NextProcess, + parser::Picker, +}; + +dispatcher!("pick", PickCommand => PickEntry); + +#[tokio::main] +async fn main() { + let mut program = DefaultProgram::new(); + program.with_dispatcher(PickCommand); + program.exec().await; +} + +pack!(NoNameProvided = ()); +pack!(ParsedPickInput = (i32, String)); + +#[chain] +async fn parse(prev: PickEntry) -> NextProcess { + // Extract arguments from `PickEntry`'s inner and create a `Picker` + let picker = Picker::new(prev.inner); + let picked = picker + // First extract the named argument + .pick_or("--age", 20) + .after(|n: i32| n.clamp(0, 100)) + // Then sequentially extract the remaining arguments + .pick_or_route((), AnyOutput::new(NoNameProvided::default())) + .unpack(); + + match picked { + Ok(value) => ParsedPickInput::new(value).to_render(), + Err(e) => e.route_renderer(), + } +} + +#[renderer] +fn render_parsed_pick_input(prev: ParsedPickInput) { + let (age, name) = prev.inner; + r_println!("Picked: name = {}, age = {}", name, age); +} + +#[renderer] +fn render_no_name_input(_prev: NoNameProvided) { + r_println!("No name provided."); +} + +gen_program!(); |
