use anyhow::anyhow; use std::env; use std::net::IpAddr; #[derive(Clone)] pub struct Config { /// the ip the server will bind to, e.g. 127.0.0.1 or ::1 pub server_address: IpAddr, /// the port the server will bind to, e.g. 3000 pub server_port: u16, /// the database connection string e.g. "postgresql://user:password@localhost:5432/database" pub database_url: String, pub secret_key: String, pub hostname: String, pub smtp_server: String, pub smtp_port: u16, pub smtp_login: Option, pub smtp_password: Option, pub smtp_tlstype: SmtpTlsType, } #[derive(Clone)] pub enum SmtpTlsType { TLS, StartTLS, NoTLS, } impl From for SmtpTlsType { fn from(value: String) -> Self { match value.as_str() { "starttls" => SmtpTlsType::StartTLS, "tls" => SmtpTlsType::TLS, _ => SmtpTlsType::NoTLS, } } } #[derive(Clone)] pub enum Environment { Development, Test, Production, } pub fn load_config(env: &Environment) -> Result { match env { Environment::Development => { dotenvy::dotenv().ok(); } Environment::Test => { dotenvy::from_filename(".env.test").ok(); } Environment::Production => { // do not load a file for prod } } let config = Config { server_address: env::var("SERVER_ADDRESS")?.parse()?, server_port: env::var("SERVER_PORT")?.parse()?, database_url: env::var("DATABASE_URL")?.parse()?, secret_key: env::var("SECRET_KEY")?, hostname: env::var("HOSTNAME")?, smtp_server: env::var("SMTP_SERVER")?, smtp_port: env::var("SMTP_PORT")?.parse()?, smtp_login: env::var("SMTP_LOGIN") .and_then(|x| Ok(Some(x))) .unwrap_or(None), smtp_password: env::var("SMTP_PASSWORD") .and_then(|x| Ok(Some(x))) .unwrap_or(None), smtp_tlstype: SmtpTlsType::from(env::var("SMTP_TLSTYPE")?), }; Ok(config) } pub fn get_env() -> Result { match env::var("APP_ENVIRONMENT") { Ok(val) => { //info!(r#"Setting environment from APP_ENVIRONMENT: "{}""#, val); parse_env(&val) } Err(_) => { //info!("Defaulting to environment: development"); Ok(Environment::Development) } } } pub fn parse_env(env: &str) -> Result { let env = &env.to_lowercase(); match env.as_str() { "dev" => Ok(Environment::Development), "development" => Ok(Environment::Development), "test" => Ok(Environment::Test), "prod" => Ok(Environment::Production), "production" => Ok(Environment::Production), unknown => Err(anyhow!(r#"Unknown environment: "{}"!"#, unknown)), } }