From 768227f7aa31e2930e1ff2641c24fbf06fc339fe Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Sat, 25 Jan 2025 10:50:26 +0100 Subject: Add 1.0.0 --- src/configuration.rs | 77 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 22 deletions(-) (limited to 'src/configuration.rs') 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, pub smtp_configuration: Arc, } 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 { + 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) -> 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), } } -- cgit