Skip to main content

airmux/
config.rs

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