pico_test_app/
pico_test_app.rs

1#![allow(dead_code)]
2//! pico-args implements this program for a number of argument parsers:
3//! https://github.com/RazrFalcon/pico-args/tree/master/test-apps
4//!
5//! It's a nice reference point.
6//!
7//! I release this implementation into the public domain. Feel free to copy.
8
9const HELP: &str = "\
10USAGE: app [OPTIONS] --number NUMBER INPUT
11
12OPTIONS:
13  --number NUMBER       Set a number (required)
14  --opt-number NUMBER   Set an optional number
15  --width WIDTH         Set a width (non-zero, default 10)
16
17ARGS:
18  <INPUT>               Input file
19";
20
21#[derive(Debug)]
22struct AppArgs {
23    number: u32,
24    opt_number: Option<u32>,
25    width: u32,
26    input: std::path::PathBuf,
27}
28
29fn parse_width(s: &str) -> Result<u32, String> {
30    let w = s.parse().map_err(|_| "not a number")?;
31    if w != 0 {
32        Ok(w)
33    } else {
34        Err("width must be positive".to_string())
35    }
36}
37
38fn main() {
39    let args = match parse_args() {
40        Ok(args) => args,
41        Err(err) => {
42            eprintln!("Error: {}.", err);
43            std::process::exit(1);
44        }
45    };
46    println!("{:#?}", args);
47}
48
49fn parse_args() -> Result<AppArgs, lexopt::Error> {
50    use lexopt::prelude::*;
51
52    let mut number = None;
53    let mut opt_number = None;
54    let mut width = 10;
55    let mut input = None;
56
57    let mut parser = lexopt::Parser::from_env();
58    while let Some(arg) = parser.next()? {
59        match arg {
60            Short('h') | Long("help") => {
61                print!("{}", HELP);
62                std::process::exit(0);
63            }
64            Long("number") => number = Some(parser.value()?.parse()?),
65            Long("opt-number") => opt_number = Some(parser.value()?.parse()?),
66            Long("width") => width = parser.value()?.parse_with(parse_width)?,
67            Value(path) if input.is_none() => input = Some(path.into()),
68            _ => return Err(arg.unexpected()),
69        }
70    }
71    Ok(AppArgs {
72        number: number.ok_or("missing required option --number")?,
73        opt_number,
74        width,
75        input: input.ok_or("missing required argument INPUT")?,
76    })
77}