hello_parser/
hello-parser.rs1struct 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}