brass/config/src/lib.rs

103 lines
2.9 KiB
Rust

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<String>,
pub smtp_password: Option<String>,
pub smtp_tlstype: SmtpTlsType,
}
#[derive(Clone)]
pub enum SmtpTlsType {
TLS,
StartTLS,
NoTLS,
}
impl From<String> 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<Config, anyhow::Error> {
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<Environment, anyhow::Error> {
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<Environment, anyhow::Error> {
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)),
}
}