use std::env; use std::path::PathBuf; use dirs::config_dir; use getopts::Options; use log::LevelFilter; #[derive(Debug)] pub struct Config { pub config_directory: PathBuf, pub log_level: LevelFilter, } impl Config { pub fn from_args() -> Config { let args: Vec = env::args().collect(); let program = args[0].clone(); let mut opts = Options::new(); opts.optopt("c", "config", "config directory", "CONFIG"); opts.optopt( "l", "level", "log level (error, warn, info, debug, trace)", "LEVEL", ); opts.optflag("h", "help", "print this help menu"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(e) => { println!("FATAL: Error parsing arguments: {:?}", e); std::process::exit(1); } }; if matches.opt_present("h") { let brief = format!("Usage: {} [options]", program); print!("{}", opts.usage(&brief)); std::process::exit(0); } let config_directory = if let Some(dir) = matches.opt_str("c") { PathBuf::from(dir) } else if let Some(mut dir) = config_dir() { dir.push("sup"); dir } else { PathBuf::from(".") }; let mut log_level: LevelFilter = LevelFilter::Info; if let Some(raw_level) = matches.opt_str("l") { log_level = match raw_level.as_str() { "error" => LevelFilter::Error, "warn" => LevelFilter::Warn, "info" => LevelFilter::Info, "debug" => LevelFilter::Debug, "trace" => LevelFilter::Trace, _ => { println!("FATAL: unknown log level: {}", raw_level); println!("Options are error, warn, info, debug, or trace"); std::process::exit(1); } }; }; Config { config_directory, log_level, } } }