Skip to main content

envvault/config/
global.rs

1//! Global user-level configuration at `~/.config/envvault/config.toml`.
2//!
3//! Provides machine-wide defaults that project-level `.envvault.toml` can override.
4
5use serde::{Deserialize, Serialize};
6
7use super::settings::AuditSettings;
8
9/// Global configuration loaded from `~/.config/envvault/config.toml`.
10#[derive(Debug, Clone, Default, Serialize, Deserialize)]
11pub struct GlobalConfig {
12    /// Default editor for `envvault edit`.
13    #[serde(default, skip_serializing_if = "Option::is_none")]
14    pub editor: Option<String>,
15
16    /// Default keyfile path.
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub keyfile_path: Option<String>,
19
20    /// Audit settings.
21    #[serde(default)]
22    pub audit: AuditSettings,
23}
24
25impl GlobalConfig {
26    /// Load the global config from `~/.config/envvault/config.toml`.
27    ///
28    /// Returns defaults if the file is missing or cannot be parsed.
29    pub fn load() -> Self {
30        let Some(path) = Self::config_path() else {
31            return Self::default();
32        };
33
34        let Ok(contents) = std::fs::read_to_string(&path) else {
35            return Self::default();
36        };
37
38        toml::from_str(&contents).unwrap_or_default()
39    }
40
41    /// Path to the global config file.
42    fn config_path() -> Option<std::path::PathBuf> {
43        let home = std::env::var("HOME")
44            .or_else(|_| std::env::var("USERPROFILE"))
45            .ok()?;
46        Some(
47            std::path::PathBuf::from(home)
48                .join(".config")
49                .join("envvault")
50                .join("config.toml"),
51        )
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn global_config_returns_defaults_when_file_missing() {
61        let config = GlobalConfig::load();
62        assert!(config.editor.is_none());
63        assert!(config.keyfile_path.is_none());
64        assert!(!config.audit.log_reads);
65    }
66}