Skip to main content

velesdb_core/update_check/
config.rs

1//! Update Check Configuration (US-002)
2//!
3//! Provides configuration options for the update check feature.
4
5use serde::Deserialize;
6
7/// Configuration for update check feature.
8///
9/// # Priority Order
10///
11/// 1. Environment variable `VELESDB_NO_UPDATE_CHECK=1` (highest)
12/// 2. Configuration file `[update_check]` section
13/// 3. Default (enabled)
14#[derive(Debug, Clone, Deserialize)]
15pub struct UpdateCheckConfig {
16    /// Enable update check (default: true)
17    #[serde(default = "default_enabled")]
18    pub enabled: bool,
19
20    /// Update check endpoint URL
21    #[serde(default = "default_endpoint")]
22    pub endpoint: String,
23
24    /// Timeout in milliseconds (default: 2000)
25    #[serde(default = "default_timeout_ms")]
26    pub timeout_ms: u64,
27}
28
29fn default_enabled() -> bool {
30    true
31}
32
33fn default_endpoint() -> String {
34    "https://velesdb.com/api/check".to_string()
35}
36
37fn default_timeout_ms() -> u64 {
38    2000
39}
40
41impl Default for UpdateCheckConfig {
42    fn default() -> Self {
43        Self {
44            enabled: default_enabled(),
45            endpoint: default_endpoint(),
46            timeout_ms: default_timeout_ms(),
47        }
48    }
49}
50
51impl UpdateCheckConfig {
52    /// Check if update check is enabled.
53    ///
54    /// Environment variables take precedence over configuration file:
55    /// - `VELESDB_NO_UPDATE_CHECK=1` or `true` → disabled
56    /// - `VELESDB_UPDATE_CHECK=0` or `false` → disabled
57    /// - `VELESDB_UPDATE_CHECK=1` or `true` → enabled
58    #[must_use]
59    pub fn is_enabled(&self) -> bool {
60        // Check negative form: VELESDB_NO_UPDATE_CHECK
61        // Only disable if explicitly set to a truthy value (not just existing)
62        if let Ok(val) = std::env::var("VELESDB_NO_UPDATE_CHECK") {
63            let val_lower = val.to_lowercase();
64            // Truthy values: "1", "true", "yes", "on", or any non-empty non-falsy value
65            if val_lower != "0" && val_lower != "false" && val_lower != "no" && val_lower != "off" {
66                return false;
67            }
68        }
69
70        // Check positive form: VELESDB_UPDATE_CHECK
71        if let Ok(val) = std::env::var("VELESDB_UPDATE_CHECK") {
72            let val_lower = val.to_lowercase();
73            return val_lower != "0"
74                && val_lower != "false"
75                && val_lower != "no"
76                && val_lower != "off";
77        }
78
79        self.enabled
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86    use serial_test::serial;
87
88    #[test]
89    #[serial(env)]
90    fn test_env_var_disables_update_check() {
91        std::env::set_var("VELESDB_NO_UPDATE_CHECK", "1");
92
93        let config = UpdateCheckConfig::default();
94        assert!(!config.is_enabled());
95
96        std::env::remove_var("VELESDB_NO_UPDATE_CHECK");
97    }
98
99    #[test]
100    #[serial(env)]
101    fn test_env_var_overrides_config() {
102        std::env::set_var("VELESDB_NO_UPDATE_CHECK", "1");
103
104        let config = UpdateCheckConfig {
105            enabled: true, // Config says yes
106            ..Default::default()
107        };
108
109        assert!(!config.is_enabled()); // But env says no
110
111        std::env::remove_var("VELESDB_NO_UPDATE_CHECK");
112    }
113
114    #[test]
115    #[serial(env)]
116    fn test_config_disabled() {
117        std::env::remove_var("VELESDB_NO_UPDATE_CHECK");
118        std::env::remove_var("VELESDB_UPDATE_CHECK");
119
120        let config = UpdateCheckConfig {
121            enabled: false,
122            ..Default::default()
123        };
124
125        assert!(!config.is_enabled());
126    }
127
128    #[test]
129    #[serial(env)]
130    fn test_default_enabled() {
131        std::env::remove_var("VELESDB_NO_UPDATE_CHECK");
132        std::env::remove_var("VELESDB_UPDATE_CHECK");
133
134        let config = UpdateCheckConfig::default();
135        assert!(config.is_enabled());
136    }
137
138    #[test]
139    fn test_default_endpoint() {
140        let config = UpdateCheckConfig::default();
141        assert_eq!(config.endpoint, "https://velesdb.com/api/check");
142    }
143
144    #[test]
145    fn test_default_timeout() {
146        let config = UpdateCheckConfig::default();
147        assert_eq!(config.timeout_ms, 2000);
148    }
149}