#[cfg(test)] use std::path::Path; use std::process; pub struct GitConfig { config: git2::Config, pub enabled: bool, pub repo: Option, } impl GitConfig { pub fn try_create() -> Option { let repo = match std::env::current_dir() { Ok(dir) => git2::Repository::discover(dir).ok(), _ => None, }; let config = match &repo { Some(repo) => repo.config().ok(), None => git2::Config::open_default().ok(), }; match config { Some(mut config) => { let config = config.snapshot().unwrap_or_else(|err| { eprintln!("Failed to read git config: {}", err); process::exit(1) }); Some(Self { config, repo, enabled: true, }) } None => None, } } #[cfg(test)] pub fn from_path(path: &Path) -> Self { Self { config: git2::Config::open(path).unwrap(), repo: None, enabled: true, } } pub fn get(&self, key: &str) -> Option where T: GitConfigGet, { if self.enabled { T::git_config_get(key, self) } else { None } } } pub trait GitConfigGet { fn git_config_get(key: &str, git_config: &GitConfig) -> Option where Self: Sized; } impl GitConfigGet for String { fn git_config_get(key: &str, git_config: &GitConfig) -> Option { git_config.config.get_string(key).ok() } } impl GitConfigGet for Option { fn git_config_get(key: &str, git_config: &GitConfig) -> Option { match git_config.config.get_string(key) { Ok(value) => Some(Some(value)), _ => None, } } } impl GitConfigGet for bool { fn git_config_get(key: &str, git_config: &GitConfig) -> Option { git_config.config.get_bool(key).ok() } } impl GitConfigGet for usize { fn git_config_get(key: &str, git_config: &GitConfig) -> Option { match git_config.config.get_i64(key) { Ok(value) => Some(value as usize), _ => None, } } } impl GitConfigGet for f64 { fn git_config_get(key: &str, git_config: &GitConfig) -> Option { match git_config.config.get_string(key) { Ok(value) => value.parse::().ok(), _ => None, } } }