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