use anyhow::anyhow; #[derive(Clone)] pub struct EnvConfig { pub http_port: u16, pub webhook_secret: String, pub open_router_api_key: String, pub open_router_model: String, pub open_router_timeout: u64, pub bot_name: String, pub bot_max_concurrent: usize, pub gitea_url: String, pub gitea_token: String, pub gitea_timeout: u64, } pub fn load_config() -> anyhow::Result { let http_port = try_get_env("HTTP_PORT")?.parse()?; let bot_name = try_get_env("BOT_NAME")?; let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?; let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?; let open_router_model = try_get_env("OPEN_ROUTER_MODEL")?; let open_router_timeout = try_get_env("OPEN_ROUTER_TIMEOUT")?.parse()?; let bot_max_concurrent = try_get_env("BOT_MAX_CONCURRENT")?.parse()?; let gitea_url = try_get_env("GITEA_URL")?; let gitea_token = try_get_env("GITEA_TOKEN")?; let gitea_timeout = try_get_env("GITEA_TIMEOUT")?.parse()?; Ok(EnvConfig { http_port, webhook_secret, bot_name, open_router_api_key, open_router_model, open_router_timeout, bot_max_concurrent, gitea_url, gitea_token, gitea_timeout, }) } pub fn try_get_env(key: &str) -> anyhow::Result { let env = std::env::var(key)?; if env.trim().is_empty() { return Err(anyhow!(format!("env var {} is empty", key))); } Ok(env) }