syncable_cli/config/
mod.rs

1pub mod types;
2
3use crate::error::Result;
4use std::fs;
5use std::path::{Path, PathBuf};
6
7const CONFIG_FILE_NAME: &str = ".syncable.toml";
8
9/// Get the global config file path (~/.syncable.toml)
10pub fn global_config_path() -> Option<PathBuf> {
11    dirs::home_dir().map(|h| h.join(CONFIG_FILE_NAME))
12}
13
14/// Get the local config file path (project/.syncable.toml)
15pub fn local_config_path(project_path: &Path) -> PathBuf {
16    project_path.join(CONFIG_FILE_NAME)
17}
18
19/// Load configuration from file or use defaults
20/// Checks local config first, then global config
21pub fn load_config(project_path: Option<&Path>) -> Result<types::Config> {
22    // Try local config first
23    if let Some(path) = project_path {
24        let local = local_config_path(path);
25        if local.exists() {
26            if let Ok(content) = fs::read_to_string(&local) {
27                if let Ok(config) = toml::from_str(&content) {
28                    return Ok(config);
29                }
30            }
31        }
32    }
33    
34    // Try global config
35    if let Some(global) = global_config_path() {
36        if global.exists() {
37            if let Ok(content) = fs::read_to_string(&global) {
38                if let Ok(config) = toml::from_str(&content) {
39                    return Ok(config);
40                }
41            }
42        }
43    }
44    
45    Ok(types::Config::default())
46}
47
48/// Save configuration to global config file
49pub fn save_global_config(config: &types::Config) -> Result<()> {
50    if let Some(path) = global_config_path() {
51        let content = toml::to_string_pretty(config)
52            .map_err(|e| crate::error::ConfigError::ParsingFailed(e.to_string()))?;
53        fs::write(&path, content)?;
54    }
55    Ok(())
56}
57
58/// Load only the agent config section (for API keys)
59pub fn load_agent_config() -> types::AgentConfig {
60    if let Some(global) = global_config_path() {
61        if global.exists() {
62            if let Ok(content) = fs::read_to_string(&global) {
63                if let Ok(config) = toml::from_str::<types::Config>(&content) {
64                    return config.agent;
65                }
66            }
67        }
68    }
69    types::AgentConfig::default()
70}
71
72/// Save agent config, preserving other config sections
73pub fn save_agent_config(agent: &types::AgentConfig) -> Result<()> {
74    let mut config = load_config(None)?;
75    config.agent = agent.clone();
76    save_global_config(&config)
77}