hello/
hello.rs

1use lexarg::LexError;
2use lexarg::Result;
3
4struct Args {
5    thing: String,
6    number: u32,
7    shout: bool,
8}
9
10fn parse_args() -> Result<Args> {
11    use lexarg::prelude::*;
12
13    let mut thing = None;
14    let mut number = 1;
15    let mut shout = false;
16    let raw = std::env::args_os().collect::<Vec<_>>();
17    let mut parser = lexarg::Parser::new(&raw);
18    let bin_name = parser
19        .next_raw()
20        .expect("nothing parsed yet so no attached lingering")
21        .expect("always at least one");
22    let mut prev_arg = Value(bin_name);
23    while let Some(arg) = parser.next_arg() {
24        match arg {
25            Short("n") | Long("number") => {
26                number = parser
27                    .next_flag_value()
28                    .ok_or_missing(Value(std::ffi::OsStr::new("NUM")))
29                    .parse()
30                    .within(arg)?;
31            }
32            Long("shout") => {
33                shout = true;
34            }
35            Value(val) if thing.is_none() => {
36                thing = Some(val.string("THING")?);
37            }
38            Short("h") | Long("help") => {
39                println!("Usage: hello [-n|--number=NUM] [--shout] THING");
40                std::process::exit(0);
41            }
42            Unexpected(_) => {
43                return Err(LexError::msg("unexpected value")
44                    .unexpected(arg)
45                    .within(prev_arg)
46                    .into());
47            }
48            _ => {
49                return Err(LexError::msg("unexpected argument").unexpected(arg).into());
50            }
51        }
52        prev_arg = arg;
53    }
54
55    Ok(Args {
56        thing: thing
57            .ok_or_missing(Value(std::ffi::OsStr::new("THING")))
58            .within(Value(bin_name))?
59            .to_owned(),
60        number,
61        shout,
62    })
63}
64
65fn main() -> Result<()> {
66    let args = parse_args()?;
67    let mut message = format!("Hello {}", args.thing);
68    if args.shout {
69        message = message.to_uppercase();
70    }
71    for _ in 0..args.number {
72        println!("{message}");
73    }
74    Ok(())
75}