X-Git-Url: https://git.r.bdr.sh/rbdr/olden-mail/blobdiff_plain/dc3d68214e2cd4b5f86279a7fa7b7d64c341b446..2fdda21d13ed742bdb52ec3ba74538af83de2bf4:/src/configuration.rs?ds=sidebyside diff --git a/src/configuration.rs b/src/configuration.rs index 1437594..49cd991 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), +} -pub struct ProxyConfiguration { +/// Configuration for any proxy +#[derive(Debug)] +pub struct Proxy { 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, - pub smtp_configuration: Arc, + pub imap_configuration: Arc, + pub smtp_configuration: Arc, } impl Configuration { - pub fn new() -> Self { - 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"), + /// Creates a new configuration object by reading the environment + /// variables. Exits if the right ones aren't found. + pub fn new() -> Result { + Ok(Configuration { + imap_configuration: Arc::new(Proxy { + 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"), + smtp_configuration: Arc::new(Proxy { + 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) -> Result { + 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 { + match env::var(name) { + Ok(value) => value + .parse() + .map_err(|_| ConfigurationError::ParseError(name.to_string())), + Err(_) => Ok(default), } }