hello_parser/
hello-parser.rs

1struct Args {
2    thing: String,
3    number: u32,
4    shout: bool,
5}
6
7fn parse_args() -> Result<Args, &'static str> {
8    #![allow(clippy::enum_glob_use)]
9    use lexarg_parser::Arg::*;
10
11    let mut thing = None;
12    let mut number = 1;
13    let mut shout = false;
14    let raw = std::env::args_os().collect::<Vec<_>>();
15    let mut parser = lexarg_parser::Parser::new(&raw);
16    let _bin_name = parser.next_raw();
17    while let Some(arg) = parser.next_arg() {
18        match arg {
19            Short("n") | Long("number") => {
20                number = parser
21                    .next_flag_value()
22                    .ok_or("`--number` requires a value")?
23                    .to_str()
24                    .ok_or("invalid number")?
25                    .parse()
26                    .map_err(|_e| "invalid number")?;
27            }
28            Long("shout") => {
29                shout = true;
30            }
31            Value(val) if thing.is_none() => {
32                thing = Some(val.to_str().ok_or("invalid string")?);
33            }
34            Short("h") | Long("help") => {
35                println!("Usage: hello [-n|--number=NUM] [--shout] THING");
36                std::process::exit(0);
37            }
38            _ => {
39                return Err("unexpected argument");
40            }
41        }
42    }
43
44    Ok(Args {
45        thing: thing.ok_or("missing argument THING")?.to_owned(),
46        number,
47        shout,
48    })
49}
50
51fn main() -> Result<(), String> {
52    let args = parse_args()?;
53    let mut message = format!("Hello {}", args.thing);
54    if args.shout {
55        message = message.to_uppercase();
56    }
57    for _ in 0..args.number {
58        println!("{message}");
59    }
60    Ok(())
61}