2.1 KiB · text History d76cd01
use sea_orm::DatabaseConnection;
use std::env;

/// Runtime configuration, sourced entirely from environment variables so the
/// same binary works in local dev, compose, and production without a config
/// file. Every field has a sensible default that matches `compose.yml`.
#[derive(Debug, Clone)]
pub struct Config {
    pub database_url: String,
    pub bind_address: String,
    pub session_duration_hours: i64,
    pub registration_token_duration_days: i64,
    /// Run pending migrations on webservice boot.
    pub auto_migrate: bool,
    /// Allow public self-registration (still requires a valid invite token).
    pub registration_enabled: bool,
    /// Absolute origin the app is reached at, used to build the copy-paste
    /// embed and image snippets (no trailing slash).
    pub public_url: String,
}

impl Config {
    pub fn from_env() -> Self {
        Config {
            database_url: env::var("DATABASE_URL").unwrap_or_else(|_| {
                "postgres://app_user:app_password@localhost:5433/app".to_string()
            }),
            bind_address: env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:3999".to_string()),
            session_duration_hours: parse_or("SESSION_DURATION_HOURS", 24),
            registration_token_duration_days: parse_or("REGISTRATION_TOKEN_DURATION_DAYS", 7),
            auto_migrate: parse_bool("AUTO_MIGRATE", true),
            registration_enabled: parse_bool("REGISTRATION_ENABLED", false),
            public_url: env::var("PUBLIC_URL")
                .unwrap_or_else(|_| "http://localhost:3999".to_string())
                .trim_end_matches('/')
                .to_string(),
        }
    }
}

fn parse_or<T: std::str::FromStr>(key: &str, default: T) -> T {
    env::var(key).ok().and_then(|v| v.parse().ok()).unwrap_or(default)
}

fn parse_bool(key: &str, default: bool) -> bool {
    env::var(key)
        .map(|v| matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on"))
        .unwrap_or(default)
}

pub async fn create_db_connection(database_url: &str) -> Result<DatabaseConnection, sea_orm::DbErr> {
    sea_orm::Database::connect(database_url).await
}