Skip to main content

subcommands/
subcommands.rs

1fn main() -> noargs::Result<()> {
2    let mut args = noargs::raw_args();
3    args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4    args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6    if noargs::VERSION_FLAG.take(&mut args).is_present() {
7        println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8        return Ok(());
9    }
10    noargs::HELP_FLAG.take_help(&mut args);
11
12    // In real applications, split each `try_run_*` command into separate modules/files.
13    let _ = try_run_hello(&mut args)? || try_run_sum(&mut args)? || try_run_echo(&mut args)?;
14
15    if let Some(help) = args.finish()? {
16        print!("{help}");
17    }
18
19    Ok(())
20}
21
22fn try_run_hello(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
23    if !noargs::cmd("hello")
24        .doc("Print a greeting")
25        .take(args)
26        .is_present()
27    {
28        return Ok(false);
29    }
30
31    let loud = noargs::flag("loud")
32        .short('l')
33        .doc("Print greeting in upper case")
34        .take(args)
35        .is_present();
36    let name: String = noargs::arg("<NAME>")
37        .doc("Name to greet")
38        .example("Alice")
39        .take(args)
40        .then(|a| a.value().parse())?;
41
42    if args.metadata().help_mode {
43        return Ok(true);
44    }
45
46    let message = format!("Hello, {name}!");
47    if loud {
48        println!("{}", message.to_uppercase());
49    } else {
50        println!("{message}");
51    }
52    Ok(true)
53}
54
55fn try_run_sum(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
56    if !noargs::cmd("sum")
57        .doc("Add two integers")
58        .take(args)
59        .is_present()
60    {
61        return Ok(false);
62    }
63
64    let repeat: usize = noargs::opt("repeat")
65        .short('r')
66        .ty("N")
67        .doc("Print result multiple times")
68        .default("1")
69        .take(args)
70        .then(|o| o.value().parse())?;
71    let left: i64 = noargs::arg("<LEFT>")
72        .doc("Left operand")
73        .example("3")
74        .take(args)
75        .then(|a| a.value().parse())?;
76    let right: i64 = noargs::arg("<RIGHT>")
77        .doc("Right operand")
78        .example("4")
79        .take(args)
80        .then(|a| a.value().parse())?;
81
82    if args.metadata().help_mode {
83        return Ok(true);
84    }
85
86    let total = left + right;
87    for _ in 0..repeat {
88        println!("{total}");
89    }
90    Ok(true)
91}
92
93fn try_run_echo(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
94    if !noargs::cmd("echo")
95        .doc("Print a message")
96        .take(args)
97        .is_present()
98    {
99        return Ok(false);
100    }
101
102    let upper = noargs::flag("upper")
103        .short('u')
104        .doc("Uppercase the message")
105        .take(args)
106        .is_present();
107    let text: String = noargs::arg("<TEXT>")
108        .doc("Message text")
109        .example("hello world")
110        .take(args)
111        .then(|a| a.value().parse())?;
112
113    if args.metadata().help_mode {
114        return Ok(true);
115    }
116
117    if upper {
118        println!("{}", text.to_uppercase());
119    } else {
120        println!("{text}");
121    }
122    Ok(true)
123}