1 use anyhow::{Error, Result};
2 use std::path::PathBuf;
3 
4 #[derive(Default)]
5 pub struct Args {
6     pub display_help: bool,
7     pub display_version: bool,
8     pub load_tutor: bool,
9     pub verbosity: u64,
10     pub files: Vec<PathBuf>,
11 }
12 
13 impl Args {
parse_args() -> Result<Args>14     pub fn parse_args() -> Result<Args> {
15         let mut args = Args::default();
16         let argv: Vec<String> = std::env::args().collect();
17         let mut iter = argv.iter();
18 
19         iter.next(); // skip the program, we don't care about that
20 
21         for arg in &mut iter {
22             match arg.as_str() {
23                 "--" => break, // stop parsing at this point treat the remaining as files
24                 "--version" => args.display_version = true,
25                 "--help" => args.display_help = true,
26                 "--tutor" => args.load_tutor = true,
27                 arg if arg.starts_with("--") => {
28                     return Err(Error::msg(format!(
29                         "unexpected double dash argument: {}",
30                         arg
31                     )))
32                 }
33                 arg if arg.starts_with('-') => {
34                     let arg = arg.get(1..).unwrap().chars();
35                     for chr in arg {
36                         match chr {
37                             'v' => args.verbosity += 1,
38                             'V' => args.display_version = true,
39                             'h' => args.display_help = true,
40                             _ => return Err(Error::msg(format!("unexpected short arg {}", chr))),
41                         }
42                     }
43                 }
44                 arg => args.files.push(PathBuf::from(arg)),
45             }
46         }
47 
48         // push the remaining args, if any to the files
49         for filename in iter {
50             args.files.push(PathBuf::from(filename));
51         }
52 
53         Ok(args)
54     }
55 }
56