Skip to main content

iris_hub/core/
config.rs

1//! # Gerenciamento de Configurações
2//! 
3//! Este módulo é responsável por carregar, salvar e gerenciar
4//! as configurações da aplicação Iris.
5//! 
6//! ## Localização do Arquivo de Configuração
7//! As configurações são salvas em: `%APPDATA%\iris\config.json`
8
9use std::fs;
10use std::path::PathBuf;
11use super::models::AppState;
12
13/// Gerenciador de configurações da aplicação.
14/// 
15/// Responsável por:
16/// - Determinar o caminho do arquivo de configuração
17/// - Carregar configurações do disco
18/// - Salvar configurações em disco
19/// - Importar/Exportar configurações
20pub struct ConfigManager {
21    /// Caminho do arquivo de configuração
22    config_path: PathBuf,
23}
24
25impl ConfigManager {
26    /// Cria uma nova instância do gerenciador de configurações.
27    /// 
28    /// Automaticamente determina o caminho correto baseado no sistema operacional.
29    pub fn new() -> Self {
30        let config_path = Self::get_config_path();
31        Self { config_path }
32    }
33    
34    /// Retorna o caminho do arquivo de configuração.
35    /// 
36    /// No Windows: `%APPDATA%\iris\config.json`
37    /// No Linux/macOS: `~/.config/iris/config.json`
38    pub fn get_config_path() -> PathBuf {
39        let mut path = dirs::config_dir().unwrap_or_else(|| PathBuf::from("."));
40        path.push("iris");
41        fs::create_dir_all(&path).ok();
42        path.push("config.json");
43        path
44    }
45    
46    /// Retorna uma referência ao caminho do arquivo de configuração
47    pub fn path(&self) -> &PathBuf {
48        &self.config_path
49    }
50    
51    /// Carrega o estado da aplicação do disco.
52    /// 
53    /// Se o arquivo não existir ou for inválido, retorna um estado vazio.
54    /// 
55    /// # Exemplo
56    /// ```rust
57    /// let manager = ConfigManager::new();
58    /// let state = manager.load();
59    /// println!("Aplicações carregadas: {}", state.apps.len());
60    /// ```
61    pub fn load(&self) -> AppState {
62        if self.config_path.exists() {
63            if let Ok(content) = fs::read_to_string(&self.config_path) {
64                if let Ok(state) = serde_json::from_str(&content) {
65                    return state;
66                }
67            }
68        }
69        AppState::default()
70    }
71    
72    /// Salva o estado da aplicação em disco.
73    /// 
74    /// # Argumentos
75    /// * `state` - Estado a ser salvo
76    /// 
77    /// # Retorno
78    /// Retorna `Ok(())` em caso de sucesso ou `Err` com a mensagem de erro.
79    pub fn save(&self, state: &AppState) -> Result<(), String> {
80        match serde_json::to_string_pretty(state) {
81            Ok(json) => {
82                fs::write(&self.config_path, json)
83                    .map_err(|e| format!("Erro ao salvar configurações: {}", e))
84            }
85            Err(e) => Err(format!("Erro ao serializar configurações: {}", e)),
86        }
87    }
88    
89    /// Exporta as configurações para um arquivo específico.
90    /// 
91    /// # Argumentos
92    /// * `state` - Estado a ser exportado
93    /// * `path` - Caminho do arquivo de destino
94    pub fn export(&self, state: &AppState, path: &PathBuf) -> Result<(), String> {
95        match serde_json::to_string_pretty(state) {
96            Ok(json) => {
97                fs::write(path, json)
98                    .map_err(|e| format!("Erro ao exportar configurações: {}", e))
99            }
100            Err(e) => Err(format!("Erro ao serializar configurações: {}", e)),
101        }
102    }
103    
104    /// Importa configurações de um arquivo.
105    /// 
106    /// As aplicações importadas recebem novos IDs para evitar conflitos.
107    /// 
108    /// # Argumentos
109    /// * `path` - Caminho do arquivo a ser importado
110    /// 
111    /// # Retorno
112    /// Retorna o estado importado ou uma mensagem de erro.
113    pub fn import(&self, path: &PathBuf) -> Result<AppState, String> {
114        let content = fs::read_to_string(path)
115            .map_err(|e| format!("Erro ao ler arquivo: {}", e))?;
116        
117        let mut state: AppState = serde_json::from_str(&content)
118            .map_err(|e| format!("Erro ao processar JSON: {}", e))?;
119        
120        // Gera novos IDs para evitar conflitos
121        for app in &mut state.apps {
122            app.id = crate::utils::uuid_simple();
123        }
124        
125        Ok(state)
126    }
127}
128
129impl Default for ConfigManager {
130    fn default() -> Self {
131        Self::new()
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138    
139    #[test]
140    fn test_config_path_exists() {
141        let path = ConfigManager::get_config_path();
142        assert!(path.to_string_lossy().contains("iris"));
143    }
144    
145    #[test]
146    fn test_default_state_is_empty() {
147        let state = AppState::default();
148        assert!(state.apps.is_empty());
149    }
150}