Skip to main content

git_comma/
config.rs

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