Skip to main content

arrays/
arrays.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    // Same-name options can be collected by calling take() in a loop.
13    let include_opt = noargs::opt("include")
14        .short('I')
15        .ty("PATH")
16        .doc("Include path (can be specified multiple times)");
17    let mut includes = Vec::<String>::new();
18    while let Some(path) = include_opt
19        .take(&mut args)
20        .present_and_then(|o| o.value().parse())?
21    {
22        includes.push(path);
23    }
24
25    let label_opt = noargs::opt("label")
26        .short('l')
27        .ty("LABEL")
28        .doc("Label value (can be specified multiple times)");
29    let mut labels = Vec::<String>::new();
30    while let Some(label) = label_opt
31        .take(&mut args)
32        .present_and_then(|o| o.value().parse())?
33    {
34        labels.push(label);
35    }
36
37    let output: String = noargs::opt("output")
38        .short('o')
39        .ty("PATH")
40        .doc("Output path")
41        .default("summary.txt")
42        .take(&mut args)
43        .then(|o| o.value().parse())?;
44
45    // Positional arrays are handled with one required argument + optional rest.
46    // Naming convention: use `<NAME>...` for required-many and `[NAME]...` for optional-many.
47    // The `<>` / `[]` / `...` markers are cosmetic (used only in help output);
48    // required-ness is enforced below: `.then()` makes the first input required,
49    // the loop with `.present_and_then()` consumes zero or more rest inputs.
50    let first_input: String = noargs::arg("<INPUT>")
51        .doc("First input (required)")
52        .example("a.txt")
53        .take(&mut args)
54        .then(|a| a.value().parse())?;
55    let rest_input_arg = noargs::arg("[INPUT]...").doc("Additional inputs");
56    let mut inputs = vec![first_input];
57    while let Some(input) = rest_input_arg
58        .take(&mut args)
59        .present_and_then(|a| a.value().parse())?
60    {
61        inputs.push(input);
62    }
63
64    if let Some(help) = args.finish()? {
65        print!("{help}");
66        return Ok(());
67    }
68
69    println!("includes={includes:?}");
70    println!("labels={labels:?}");
71    println!("inputs={inputs:?}");
72    println!("output={output}");
73    Ok(())
74}