1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use crate::utils; use app_dirs::{get_app_root, AppDataType, AppInfo}; use clap::ArgMatches; use mkdirp::mkdirp; use snafu::{ensure, Snafu}; use std::error; use std::path::{Path, PathBuf}; #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("app_name cannot be empty"))] AppNameEmpty {}, #[snafu(display("app_author cannot be empty"))] AppAuthorEmpty {}, #[snafu(display("tmux command cannot be empty"))] TmuxCommandEmpty {}, #[snafu(display("config-dir {:?} should be a directory", path))] ConfigDirIsNotADirectory { path: PathBuf }, } pub struct Config { pub app_name: &'static str, pub app_author: &'static str, pub tmux_command: Option<String>, pub config_dir: Option<PathBuf>, } impl Config { pub fn from_args( app_name: &'static str, app_author: &'static str, matches: &ArgMatches, ) -> Config { let tmux_command = matches.value_of_lossy("tmux_command").map(String::from); let config_dir = matches.value_of_os("config_dir").map(PathBuf::from); Config { app_name, app_author, tmux_command, config_dir, } } pub fn check(self) -> Result<Self, Box<dyn error::Error>> { ensure!(!&self.app_name.is_empty(), AppNameEmpty {}); ensure!(!&self.app_author.is_empty(), AppAuthorEmpty {}); if let Some(config_dir) = &self.config_dir { let path = PathBuf::from(config_dir); ensure!(!path.is_file(), ConfigDirIsNotADirectory { path }); mkdirp(&config_dir)?; }; Ok(self) } pub fn get_config_dir<P>(&self, sub_path: P) -> Result<PathBuf, Box<dyn error::Error>> where P: AsRef<Path>, { let path; if let Some(dir) = &self.config_dir { path = PathBuf::from(dir); } else { path = get_app_root( AppDataType::UserConfig, &AppInfo { name: &self.app_name, author: &self.app_author, }, )?; }; let path = path.join(&sub_path); mkdirp(&path)?; Ok(path) } pub fn get_projects_dir<P>(&self, sub_path: P) -> Result<PathBuf, Box<dyn error::Error>> where P: AsRef<Path>, { self.get_config_dir(sub_path) } pub fn get_tmux_command( &self, args: &[&str], ) -> Result<(String, Vec<String>), Box<dyn error::Error>> { let command = self .tmux_command .to_owned() .unwrap_or_else(|| String::from("tmux")); utils::parse_command(&command, args) } } #[cfg(test)] #[path = "test/config.rs"] mod tests;