//! Config operations. use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use crate::config::types::{ConfigEntry, ConfigSnapshot}; use crate::{GitDomain, GitError, GitResult}; impl GitDomain { /// Open the repository-level config. pub fn config(&self) -> GitResult { let cfg = self .repo() .config() .map_err(|e| GitError::ConfigError(e.to_string()))?; Ok(GitConfig { inner: Rc::new(RefCell::new(cfg)), }) } pub fn config_get(&self, key: &str) -> GitResult> { let cfg = self.config()?; cfg.get_str(key) .map(Some) .map_err(|e| GitError::ConfigError(e.to_string())) } pub fn config_set(&self, key: &str, value: &str) -> GitResult<()> { let cfg = self.config()?; cfg.set(key, value) .map_err(|e| GitError::ConfigError(e.to_string())) } pub fn config_delete(&self, key: &str) -> GitResult<()> { let cfg = self.config()?; cfg.delete(key) .map_err(|e| GitError::ConfigError(e.to_string())) } /// List all config entries. Optionally filter by key prefix (e.g. "user"). pub fn config_entries(&self, prefix: Option<&str>) -> GitResult { let cfg = self.config()?; let mut entries = Vec::new(); let glob = prefix.filter(|p| !p.is_empty()); let binding = cfg.inner.borrow(); let _ = binding .entries(glob) .map_err(|e: git2::Error| GitError::ConfigError(e.to_string()))? .for_each(|entry| { let name = entry.name().unwrap_or("").to_string(); let value = entry.value().unwrap_or("").to_string(); entries.push(ConfigEntry { name, value }); }); Ok(ConfigSnapshot { entries }) } pub fn config_has(&self, key: &str) -> GitResult { let cfg = self.config()?; Ok(cfg.get_str(key).is_ok()) } pub fn config_get_family(&self, prefix: &str) -> GitResult> { let snapshot = self.config_entries(Some(prefix))?; Ok(snapshot .entries .into_iter() .map(|e| (e.name, e.value)) .collect()) } } /// A wrapper around git2::Config providing a cleaner API. pub struct GitConfig { inner: Rc>, } impl GitConfig { fn get_str(&self, key: &str) -> Result { self.inner.borrow().get_str(key).map(String::from) } fn set(&self, key: &str, value: &str) -> Result<(), git2::Error> { self.inner.borrow_mut().set_str(key, value) } fn delete(&self, key: &str) -> Result<(), git2::Error> { self.inner.borrow_mut().remove(key) } }