Skip to main content

pray_core/
config.rs

1use crate::{PrayError, PrayResult};
2use serde::Deserialize;
3use std::collections::BTreeMap;
4use std::fs;
5use std::path::{Path, PathBuf};
6
7#[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq)]
8pub struct PrayConfig {
9    #[serde(default)]
10    pub local: PrayLocalConfig,
11}
12
13#[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq)]
14pub struct PrayLocalConfig {
15    #[serde(default)]
16    pub package: BTreeMap<String, String>,
17    #[serde(default)]
18    pub source: BTreeMap<String, String>,
19}
20
21pub fn load_user_config() -> PrayResult<PrayConfig> {
22    let Some(path) = user_config_path() else {
23        return Ok(PrayConfig::default());
24    };
25    if !path.is_file() {
26        return Ok(PrayConfig::default());
27    }
28    let text = fs::read_to_string(&path)?;
29    toml::from_str(&text).map_err(|error| PrayError::Parse {
30        kind: "config",
31        message: format!("{}: {error}", path.display()),
32    })
33}
34
35pub fn user_config_path() -> Option<PathBuf> {
36    if let Ok(path) = std::env::var("PRAY_CONFIG") {
37        return Some(PathBuf::from(path));
38    }
39    if let Ok(home) = std::env::var("PRAY_HOME") {
40        let path = Path::new(&home).join("config.toml");
41        if path.is_file() {
42            return Some(path);
43        }
44    }
45    home_directory().map(|home| home.join(".config").join("pray").join("config.toml"))
46}
47
48fn home_directory() -> Option<PathBuf> {
49    std::env::var_os("HOME").map(PathBuf::from)
50}
51
52#[cfg(test)]
53mod tests {
54    use super::PrayConfig;
55
56    #[test]
57    fn parses_local_override_tables() {
58        let config: PrayConfig = toml::from_str(
59            r#"
60[local.package]
61"sample/base" = "../fork"
62
63[local.source]
64dist = "../distribution/prayers"
65"#,
66        )
67        .expect("config");
68        assert_eq!(
69            config.local.package.get("sample/base").map(String::as_str),
70            Some("../fork")
71        );
72        assert_eq!(
73            config.local.source.get("dist").map(String::as_str),
74            Some("../distribution/prayers")
75        );
76    }
77}