Skip to main content

git_comma/
config.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Config {
6    pub api_key: String,
7    pub model_id: String,
8}
9
10impl Config {
11    pub fn load_from_path(path: &std::path::Path) -> Result<Self, ConfigError> {
12        let content = std::fs::read_to_string(path)?;
13        let config: Config =
14            serde_json::from_str(&content).map_err(|_| ConfigError::MalformedJson)?;
15        Ok(config)
16    }
17
18    pub fn save(&self, path: &std::path::Path) -> Result<(), ConfigError> {
19        let tmp_path = path.with_extension("json.tmp");
20        {
21            let mut file = std::fs::File::create(&tmp_path)?;
22            serde_json::to_writer_pretty(&mut file, self)?;
23        }
24
25        #[cfg(unix)]
26        {
27            use std::os::unix::fs::PermissionsExt;
28            let mut perms = std::fs::metadata(&tmp_path)?.permissions();
29            perms.set_mode(0o600);
30            std::fs::set_permissions(&tmp_path, perms)?;
31        }
32
33        std::fs::rename(&tmp_path, path)?;
34
35        Ok(())
36    }
37}
38
39#[derive(Debug)]
40pub enum ConfigError {
41    IoError(std::io::Error),
42    MalformedJson,
43    Unauthorized,
44    ApiError(String),
45}
46
47impl fmt::Display for ConfigError {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        match self {
50            ConfigError::IoError(e) => write!(f, "IO error: {}", e),
51            ConfigError::MalformedJson => write!(f, "Malformed JSON"),
52            ConfigError::Unauthorized => write!(f, "API key is invalid or expired"),
53            ConfigError::ApiError(msg) => write!(f, "API error: {}", msg),
54        }
55    }
56}
57
58impl From<std::io::Error> for ConfigError {
59    fn from(e: std::io::Error) -> Self {
60        ConfigError::IoError(e)
61    }
62}
63
64impl From<serde_json::Error> for ConfigError {
65    fn from(_: serde_json::Error) -> Self {
66        ConfigError::MalformedJson
67    }
68}
69
70pub fn home_config_path() -> std::path::PathBuf {
71    let home = home::home_dir().expect("Cannot find home directory");
72    home.join(".comma.json")
73}