Skip to main content

hs_relmon/
config.rs

1// SPDX-License-Identifier: MPL-2.0
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Debug, Default, Serialize, Deserialize)]
7pub struct Config {
8    pub gitlab: Option<GitlabConfig>,
9}
10
11#[derive(Debug, Serialize, Deserialize)]
12pub struct GitlabConfig {
13    pub access_token: String,
14}
15
16pub fn config_path() -> Result<PathBuf, Box<dyn std::error::Error>> {
17    let config_dir = std::env::var("XDG_CONFIG_HOME")
18        .map(PathBuf::from)
19        .unwrap_or_else(|_| {
20            let home = std::env::var("HOME")
21                .unwrap_or_else(|_| ".".into());
22            PathBuf::from(home).join(".config")
23        });
24    Ok(config_dir.join("hs-relmon").join("config.toml"))
25}
26
27pub fn load() -> Result<Config, Box<dyn std::error::Error>> {
28    let path = config_path()?;
29    let contents = std::fs::read_to_string(&path)?;
30    Ok(toml::from_str(&contents)?)
31}
32
33pub fn save(config: &Config) -> Result<(), Box<dyn std::error::Error>> {
34    let path = config_path()?;
35    if let Some(parent) = path.parent() {
36        std::fs::create_dir_all(parent)?;
37    }
38    let contents = toml::to_string_pretty(config)?;
39    std::fs::write(&path, contents)?;
40    Ok(())
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn test_config_deserialize() {
49        let toml_str = r#"
50[gitlab]
51access_token = "glpat-abc123"
52"#;
53        let config: Config = toml::from_str(toml_str).unwrap();
54        assert_eq!(
55            config.gitlab.as_ref().unwrap().access_token,
56            "glpat-abc123"
57        );
58    }
59
60    #[test]
61    fn test_config_deserialize_no_gitlab() {
62        let config: Config = toml::from_str("").unwrap();
63        assert!(config.gitlab.is_none());
64    }
65
66    #[test]
67    fn test_config_serialize() {
68        let config = Config {
69            gitlab: Some(GitlabConfig {
70                access_token: "glpat-abc123".into(),
71            }),
72        };
73        let s = toml::to_string_pretty(&config).unwrap();
74        assert!(s.contains("[gitlab]"));
75        assert!(s.contains("access_token = \"glpat-abc123\""));
76    }
77
78    #[test]
79    fn test_config_roundtrip() {
80        let config = Config {
81            gitlab: Some(GitlabConfig {
82                access_token: "test-token".into(),
83            }),
84        };
85        let s = toml::to_string_pretty(&config).unwrap();
86        let parsed: Config = toml::from_str(&s).unwrap();
87        assert_eq!(
88            parsed.gitlab.unwrap().access_token,
89            "test-token"
90        );
91    }
92
93    #[test]
94    fn test_config_path() {
95        let path = config_path().unwrap();
96        assert!(path.ends_with("hs-relmon/config.toml"));
97    }
98}