aboutsummaryrefslogtreecommitdiff
path: root/mingling/src/example_docs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling/src/example_docs.rs')
-rw-r--r--mingling/src/example_docs.rs382
1 files changed, 382 insertions, 0 deletions
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
new file mode 100644
index 0000000..ec8162e
--- /dev/null
+++ b/mingling/src/example_docs.rs
@@ -0,0 +1,382 @@
+// Auto generated
+
+/// `Mingling` Example - Basic
+///
+/// # How to Run
+/// ```bash
+/// cargo run --manifest-path ./examples/example-basic/Cargo.toml -- hello World
+/// ```
+///
+/// Cargo.toml
+/// ```
+/// [package]
+/// name = "example-basic"
+/// version = "0.0.1"
+/// edition = "2024"
+///
+/// [dependencies]
+/// mingling = { path = "../../mingling" }
+/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
+/// ```
+///
+/// main.rs
+/// ```rust
+/// 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 = ThisProgram::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 `ThisProgram`, 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 `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_basic {}
+/// `Mingling` Example - Completion
+///
+/// # How to Deploy
+/// 1. Enable the `comp` feature
+/// ```toml
+/// mingling = { version = "0.1.5", features = [
+/// "comp", // Enable this feature
+/// "parser"
+/// ] }
+/// ```
+///
+/// 2. Write `build.rs` to generate completion scripts at compile time
+/// ```rust
+/// use mingling::build::{build_comp_scripts, build_comp_scripts_with_bin_name};
+/// fn main() {
+/// // Generate completion scripts for the current program
+/// build_comp_scripts().unwrap();
+///
+/// // Or specify a specific name
+/// // build_comp_scripts_with_bin_name("your_bin").unwrap();
+/// }
+/// ```
+///
+/// 3. Write `main.rs`, adding completion logic for your command entry point
+/// 4. Execute `cargo install --path ./`, then run the corresponding completion script in your shell
+///
+/// Cargo.toml
+/// ```
+/// [package]
+/// name = "example-completion"
+/// version = "0.0.1"
+/// edition = "2024"
+///
+/// [dependencies]
+/// mingling = { path = "../../mingling", features = ["comp", "parser"] }
+/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
+/// ```
+///
+/// main.rs
+/// ```rust
+/// use mingling::{
+/// AnyOutput, Groupped, ShellContext, Suggest,
+/// macros::{chain, completion, dispatcher, gen_program, r_println, renderer, suggest},
+/// marker::NextProcess,
+/// parser::{Pickable, Picker},
+/// };
+///
+/// // Define dispatcher `FruitCommand`, directing subcommand "fruit" to `FruitEntry`
+/// dispatcher!("fruit", FruitCommand => FruitEntry);
+///
+/// #[completion(FruitEntry)]
+/// fn comp_fruit_command(ctx: &ShellContext) -> Suggest {
+/// if ctx.current_word.starts_with("-") {
+/// return suggest! {
+/// "--name": "Fruit name",
+/// "--type": "Fruit type"
+/// };
+/// }
+/// if ctx.previous_word == "--name" {
+/// return suggest!();
+/// }
+/// if ctx.previous_word == "--type" {
+/// return suggest! {
+/// "apple", "banana"
+/// };
+/// }
+/// return suggest!();
+/// }
+///
+/// #[tokio::main]
+/// async fn main() {
+/// let mut program = ThisProgram::new();
+/// program.with_dispatcher(CompletionDispatcher); // Add completion dispatcher
+/// program.with_dispatcher(FruitCommand);
+/// program.exec().await;
+/// }
+///
+/// #[derive(Groupped)]
+/// struct FruitInfo {
+/// name: String,
+/// fruit_type: FruitType,
+/// }
+///
+/// #[derive(Default, Debug)]
+/// enum FruitType {
+/// #[default]
+/// Apple,
+/// Banana,
+/// Other(String),
+/// }
+///
+/// impl Pickable for FruitType {
+/// type Output = FruitType;
+///
+/// fn pick(args: &mut mingling::parser::Argument, flag: mingling::Flag) -> Option<Self::Output> {
+/// let name = args.pick_argument(flag);
+/// match name {
+/// Some(name) => match name.as_str() {
+/// "apple" => Some(FruitType::Apple),
+/// "banana" => Some(FruitType::Banana),
+/// other => Some(FruitType::Other(other.to_string())),
+/// },
+/// None => None,
+/// }
+/// }
+/// }
+///
+/// #[chain]
+/// async fn parse_fruit_info(prev: FruitEntry) -> NextProcess {
+/// let picker = Picker::<ThisProgram>::from(prev.inner);
+/// let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack_directly();
+/// let info = FruitInfo {
+/// name: fruit_name,
+/// fruit_type,
+/// };
+/// AnyOutput::new(info).route_renderer()
+/// }
+///
+/// #[renderer]
+/// fn render_fruit(prev: FruitInfo) {
+/// if let FruitType::Other(other) = prev.fruit_type {
+/// r_println!("Fruit name: {}, Type: {:?} (Unknown)", prev.name, other);
+/// } else {
+/// r_println!("Fruit name: {}, Type: {:?}", prev.name, prev.fruit_type);
+/// }
+/// }
+///
+/// gen_program!();
+/// ```
+pub mod example_completion {}
+/// `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
+/// ```
+///
+/// Will print:
+/// ```plain
+/// Bob is 22 years old
+/// {"member_name":"Bob","member_age":22}
+/// member_name: Bob
+/// member_age: 22
+/// ```
+///
+/// Cargo.toml
+/// ```
+/// [package]
+/// name = "example-general-renderer"
+/// version = "0.0.1"
+/// edition = "2024"
+///
+/// [dependencies]
+/// mingling = { path = "../../mingling", features = [
+/// "parser",
+/// "general_renderer",
+/// ] }
+/// serde = { version = "1", features = ["derive"] }
+/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
+/// ```
+///
+/// main.rs
+/// ```rust
+/// 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 = ThisProgram::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<ThisProgram>>::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!();
+/// ```
+pub mod example_general_renderer {}
+/// `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
+/// ```
+///
+/// Cargo.toml
+/// ```
+/// [package]
+/// name = "example-picker"
+/// version = "0.0.1"
+/// edition = "2024"
+///
+/// [dependencies]
+/// mingling = { path = "../../mingling", features = ["parser"] }
+/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
+/// ```
+///
+/// main.rs
+/// ```rust
+/// 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 = ThisProgram::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!();
+/// ```
+pub mod example_picker {} \ No newline at end of file