aboutsummaryrefslogtreecommitdiff
path: root/examples/example-clap-binding/src/main.rs
blob: aed437d94bfdf5962c8d5f35a289efd0dd40ba9f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Example Clap Binding
//!
//! > This example demonstrates how to bind clap_derive to Mingling
//!
//! **Note**:
//! If the `error` parameter of the `dispatcher_clap!` macro is enabled, arguments will be parsed using `try_parse_from`.
//! If you need such output to support ANSI colors, enable the `color` feature of `clap`.
//!
//! Run:
//! ```bash
//! cargo run --manifest-path examples/example-clap-binding/Cargo.toml --quiet -- greet
//! cargo run --manifest-path examples/example-clap-binding/Cargo.toml --quiet -- greet Alice
//! cargo run --manifest-path examples/example-clap-binding/Cargo.toml --quiet -- greet Alice -r 5
//! cargo run --manifest-path examples/example-clap-binding/Cargo.toml --quiet -- greet --help
//! cargo run --manifest-path examples/example-clap-binding/Cargo.toml --quiet -- greet --rppat
//! ```
//!
//! Output:
//! ```plaintext
//! Hello, World!
//! Hello, Alice!
//! Hello, Alice, Alice, Alice, Alice, Alice!
//! Usage: example-clap-binding [OPTIONS] [NAME]
//!
//! Arguments:
//!   [NAME]  [default: World]
//!
//! Options:
//!   -r, --repeat <REPEAT>  [default: 1]
//!   -h, --help             Print help
//!
//! error: unexpected argument '--rppat' found
//!
//!   tip: a similar argument exists: '--repeat'
//!
//! Usage: example-clap-binding --repeat <REPEAT> [NAME]
//!
//! For more information, try '--help'.
//! ```

use mingling::{macros::dispatcher_clap, prelude::*, setup::BasicProgramSetup, Groupped};

fn main() {
    let mut program = ThisProgram::new();

    // --------- IMPORTANT ---------
    // Introduce BasicProgramSetup to support ["--help", "-h"] options
    program.with_setup(BasicProgramSetup);

    // Set clap help output mode
    program.stdout_setting.clap_help_print_behaviour =
        mingling::ClapHelpPrintBehaviour::WriteToRenderResult;
    //  mingling::ClapHelpPrintBehaviour::PrintDirectly
    //
    // PrintDirectly:
    //   Let Clap print help information directly to stdout
    //
    // WriteToRenderResult:
    //   Capture Clap's help information and write to RenderResult
    // --------- IMPORTANT ---------

    program.with_dispatcher(CMDGreet);
    program.exec_and_exit();
}

// Implement Clap Parser, and bind to Dispatcher
//        _______________________________ Default trait, provides fallback on parse failure
//       /         ______________________ clap::Parser, parsing logic implemented by Clap
//       |        /              ________ Implement mingling::Groupped
//       |        |             /           to ensure Mingling can recognize the type
//       vvvvvvv  vvvvvvvvvvvv  vvvvvvvv
#[derive(Default, clap::Parser, Groupped)]
#[dispatcher_clap(
    "greet", CMDGreet,       // Bind EntryGreet to "greet" command
    help = true,             // Generate clap help for EntryGreet
    error = ErrorGreetParsed // Generate and bind error type for parse failure
//  ^^^^^\__ Using `error` intercepts parse failure information into the specified type,
//              which is then rendered by the renderer
)]
pub struct EntryGreet {
    // Positional argument
    #[clap(default_value = "World")]
    name: String,

    // Option argument
    #[arg(short, long, default_value_t = 1)]
    repeat: i32,
}

#[renderer]
fn render_greet(greet: EntryGreet) {
    let name = greet.name;
    let count = greet.repeat.max(0) as usize;

    r_print!("Hello, ");
    for i in 0..count {
        r_print!("{name}");
        if i < count - 1 {
            r_print!(", ");
        }
    }
    r_println!("!");
}

#[renderer]
fn render_greet_parse_failed(err: ErrorGreetParsed) {
    r_println!("{}", err.to_string());
}

gen_program!();