diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-01-25 10:50:26 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-01-25 10:50:26 +0100 |
| commit | 768227f7aa31e2930e1ff2641c24fbf06fc339fe (patch) | |
| tree | ae4bf7bf696e67fedad8c8412fdd4172a51120a6 /src/configuration.rs | |
| parent | dc3d68214e2cd4b5f86279a7fa7b7d64c341b446 (diff) | |
Add 1.0.0
Diffstat (limited to 'src/configuration.rs')
| -rw-r--r-- | src/configuration.rs | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/src/configuration.rs b/src/configuration.rs index 1437594..af5c46d 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -1,45 +1,78 @@ +//! # Configuration +//! +//! This module defines the configuration used to initialize both proxies. + +use log::error; use std::env; +use std::fmt::Debug; use std::sync::Arc; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ConfigurationError { + #[error("Environment variable {0} not set.")] + MissingEnvVar(String), + #[error("Failed to parse {0}.")] + ParseError(String), +} +/// Configuration for any proxy +#[derive(Debug)] pub struct ProxyConfiguration { pub local_port: u16, - pub remote_domain: String, + pub bind_address: String, + pub remote_host: String, pub remote_port: u16, pub protocol: &'static str, } +/// Aggregated configuration for both proxies, already in a reference counter. pub struct Configuration { pub imap_configuration: Arc<ProxyConfiguration>, pub smtp_configuration: Arc<ProxyConfiguration>, } impl Configuration { - pub fn new() -> Self { - Configuration { + /// Creates a new configuration object by reading the environment + /// variables. Exits if the right ones aren't found. + pub fn new() -> Result<Self, ConfigurationError> { + Ok(Configuration { imap_configuration: Arc::new(ProxyConfiguration { - local_port: env::var("LOCAL_IMAP_PORT") - .expect("LOCAL_IMAP_PORT not set") - .parse() - .expect("Invalid LOCAL_IMAP_PORT"), - remote_domain: env::var("REMOTE_IMAP_DOMAIN").expect("REMOTE_IMAP_DOMAIN not set"), - remote_port: env::var("REMOTE_IMAP_PORT") - .expect("REMOTE_IMAP_PORT not set") - .parse() - .expect("Invalid REMOTE_IMAP_PORT"), + local_port: get_env_number("LOCAL_IMAP_PORT", 143)?, + bind_address: get_env_var("LOCAL_IMAP_BIND_ADDRESS", Some("0.0.0.0".to_string()))?, + remote_host: get_env_var("REMOTE_IMAP_DOMAIN", None)?, + remote_port: get_env_number("REMOTE_IMAP_PORT", 993)?, protocol: "IMAP", }), smtp_configuration: Arc::new(ProxyConfiguration { - local_port: env::var("LOCAL_SMTP_PORT") - .expect("LOCAL_SMTP_PORT not set") - .parse() - .expect("Invalid LOCAL_SMTP_PORT"), - remote_domain: env::var("REMOTE_SMTP_DOMAIN").expect("REMOTE_SMTP_DOMAIN not set"), - remote_port: env::var("REMOTE_SMTP_PORT") - .expect("REMOTE_SMTP_PORT not set") - .parse() - .expect("Invalid REMOTE_SMTP_PORT"), + local_port: get_env_number("LOCAL_SMTP_PORT", 25)?, + bind_address: get_env_var("LOCAL_SMTP_BIND_ADDRESS", Some("0.0.0.0".to_string()))?, + remote_host: get_env_var("REMOTE_SMTP_DOMAIN", None)?, + remote_port: get_env_number("REMOTE_SMTP_PORT", 993)?, protocol: "SMTP", }), - } + }) + } +} + +/// Get an environment variable or return an error. +fn get_env_var(name: &str, default: Option<String>) -> Result<String, ConfigurationError> { + match env::var(name) { + Ok(value) => Ok(value), + Err(_) => match default { + Some(default_value) => Ok(default_value), + None => Err(ConfigurationError::MissingEnvVar(name.to_string())), + }, + } +} + +/// Get an environment variable and parse it as a number. Return a default +/// if not set. +fn get_env_number(name: &str, default: u16) -> Result<u16, ConfigurationError> { + match env::var(name) { + Ok(value) => value + .parse() + .map_err(|_| ConfigurationError::ParseError(name.to_string())), + Err(_) => Ok(default), } } |