Skip to main content

ferro_deployments/
config.rs

1//! Deployment configuration.
2
3/// Deployment system configuration.
4#[derive(Debug, Clone, Default)]
5pub struct DeploymentConfig {
6    /// Domain for preview subdomain URLs (`DEPLOYMENT_PREVIEW_DOMAIN` env var).
7    pub preview_domain: Option<String>,
8}
9
10impl DeploymentConfig {
11    /// Create configuration from environment variables.
12    ///
13    /// Reads:
14    /// - `DEPLOYMENT_PREVIEW_DOMAIN`: domain for preview URLs (optional)
15    ///
16    /// # Example
17    ///
18    /// ```rust,ignore
19    /// use ferro_deployments::DeploymentConfig;
20    ///
21    /// let config = DeploymentConfig::from_env();
22    /// ```
23    pub fn from_env() -> Self {
24        Self {
25            preview_domain: std::env::var("DEPLOYMENT_PREVIEW_DOMAIN").ok(),
26        }
27    }
28
29    /// Set the preview domain.
30    pub fn with_preview_domain(mut self, domain: impl Into<String>) -> Self {
31        self.preview_domain = Some(domain.into());
32        self
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use serial_test::serial;
40
41    /// Guard that removes environment variables on drop, ensuring cleanup even on panic.
42    struct EnvGuard {
43        vars: Vec<String>,
44    }
45
46    impl EnvGuard {
47        fn new() -> Self {
48            Self { vars: Vec::new() }
49        }
50
51        fn also_set(&mut self, key: &str, value: &str) {
52            std::env::set_var(key, value);
53            self.vars.push(key.to_string());
54        }
55
56        fn also_remove(&mut self, key: &str) {
57            std::env::remove_var(key);
58            self.vars.push(key.to_string());
59        }
60    }
61
62    impl Drop for EnvGuard {
63        fn drop(&mut self) {
64            for var in &self.vars {
65                std::env::remove_var(var);
66            }
67        }
68    }
69
70    #[test]
71    #[serial]
72    fn preview_domain_from_env() {
73        let mut guard = EnvGuard::new();
74        guard.also_set("DEPLOYMENT_PREVIEW_DOMAIN", "preview.example.test");
75
76        let config = DeploymentConfig::from_env();
77        assert_eq!(
78            config.preview_domain,
79            Some("preview.example.test".to_string())
80        );
81    }
82
83    #[test]
84    #[serial]
85    fn preview_domain_none_when_unset() {
86        let mut guard = EnvGuard::new();
87        guard.also_remove("DEPLOYMENT_PREVIEW_DOMAIN");
88
89        let config = DeploymentConfig::from_env();
90        assert_eq!(config.preview_domain, None);
91    }
92}