1#![allow(dead_code)]
2
3const HELP: &str = "\
4App
5
6USAGE:
7 app [OPTIONS] --number NUMBER [INPUT]
8
9FLAGS:
10 -h, --help Prints help information
11
12OPTIONS:
13 --number NUMBER Sets a number
14 --opt-number NUMBER Sets an optional number
15 --width WIDTH Sets width [default: 10]
16 --output PATH Sets an output path
17
18ARGS:
19 <INPUT>
20";
21
22#[derive(Debug)]
23struct AppArgs {
24 number: u32,
25 opt_number: Option<u32>,
26 width: u32,
27 input: std::path::PathBuf,
28 output: Option<std::path::PathBuf>,
29}
30
31fn main() {
32 let args = match parse_args() {
33 Ok(v) => v,
34 Err(e) => {
35 eprintln!("Error: {}.", e);
36 std::process::exit(1);
37 }
38 };
39
40 println!("{:#?}", args);
41}
42
43fn parse_args() -> Result<AppArgs, pico_args::Error> {
44 let mut pargs = pico_args::Arguments::from_env();
45
46 if pargs.contains(["-h", "--help"]) {
48 print!("{}", HELP);
49 std::process::exit(0);
50 }
51
52 let args = AppArgs {
53 number: pargs.value_from_str("--number")?,
56 opt_number: pargs.opt_value_from_str("--opt-number")?,
58 width: pargs.opt_value_from_fn("--width", parse_width)?.unwrap_or(10),
60 output: pargs.opt_value_from_os_str("--input", parse_path)?,
62 input: pargs.free_from_str()?,
64 };
65
66 let remaining = pargs.finish();
68 if !remaining.is_empty() {
69 eprintln!("Warning: unused arguments left: {:?}.", remaining);
70 }
71
72 Ok(args)
73}
74
75fn parse_width(s: &str) -> Result<u32, &'static str> {
76 s.parse().map_err(|_| "not a number")
77}
78
79fn parse_path(s: &std::ffi::OsStr) -> Result<std::path::PathBuf, &'static str> {
80 Ok(s.into())
81}