tempo_cli/utils/
config.rs

1use crate::models::Config;
2use anyhow::Result;
3use std::collections::HashMap;
4use std::path::PathBuf;
5
6pub fn get_config_dir() -> Result<PathBuf> {
7    let config_dir = dirs::config_dir()
8        .or_else(|| dirs::home_dir())
9        .ok_or_else(|| anyhow::anyhow!("Could not determine config directory"))?;
10    
11    let tempo_dir = config_dir.join(".tempo");
12    std::fs::create_dir_all(&tempo_dir)?;
13    
14    Ok(tempo_dir)
15}
16
17pub fn get_config_path() -> Result<PathBuf> {
18    Ok(get_config_dir()?.join("config.toml"))
19}
20
21pub fn load_config() -> Result<Config> {
22    let config_path = get_config_path()?;
23    
24    if config_path.exists() {
25        let contents = std::fs::read_to_string(&config_path)?;
26        let config: Config = toml::from_str(&contents)
27            .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}. Please check the file format.", e))?;
28        
29        config.validate()?;
30        Ok(config)
31    } else {
32        let default_config = Config::default();
33        save_config(&default_config)?;
34        Ok(default_config)
35    }
36}
37
38pub fn save_config(config: &Config) -> Result<()> {
39    config.validate()?;
40    
41    let config_path = get_config_path()?;
42    let mut contents = toml::to_string_pretty(config)?;
43    
44    // Remove empty [custom_settings] section if it was written (handle various formats)
45    if config.custom_settings.is_empty() {
46        // Remove standalone [custom_settings] line
47        contents = contents.replace("[custom_settings]\n", "");
48        contents = contents.replace("\n[custom_settings]", "");
49        // Remove [custom_settings] at the end of file
50        contents = contents.replace("\n[custom_settings]", "");
51        // Clean up any double newlines
52        contents = contents.replace("\n\n\n", "\n\n");
53    }
54    
55    std::fs::write(&config_path, contents.trim_end().to_string() + "\n")?;
56    
57    Ok(())
58}