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}