diff --git a/src/config.rs b/src/config.rs index 876ba57..debec4b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,16 @@ -use std::io::{self, Write}; +use std::{ + env::var, + error::Error, + io::{self, Write}, + time::Duration, +}; use env_logger::fmt::Formatter; -use log::Record; +use log::{LevelFilter, Record}; +use sqlx::PgPool; + +/// Mnemosyne, the mother of the nine muses +pub const DEFAULT_PORT: u16 = 0x9999; // 39321 pub const REFERENCE_SPLASHES: &[&str] = &[ "quote engine", @@ -17,6 +26,44 @@ pub const REFERENCE_SPLASHES: &[&str] = &[ "over 100 lines of git history!", ]; +pub async fn init_pool() -> Result> { + Ok(sqlx::postgres::PgPoolOptions::new() + .max_connections(20) + .acquire_timeout(Duration::from_secs(3)) + .idle_timeout(Duration::from_secs(60)) + .connect(var("DATABASE_URL")?.as_str()) + .await?) +} + +pub fn port() -> Result> { + Ok(match std::env::var("PORT") { + Ok(p) => p.parse::()?, + Err(e) => match e { + std::env::VarError::NotPresent => DEFAULT_PORT, + _ => return Err(e)?, + }, + }) +} + +pub fn dotenv() -> Result<(), Box> { + if let Err(e) = dotenvy::dotenv() + && !e.not_found() + { + return Err(e.into()); + } + Ok(()) +} + +pub fn env_logger() -> Result<(), Box> { + env_logger::builder() + .filter_level(LevelFilter::Info) + .filter_module("sqlx", LevelFilter::Warn) + .parse_default_env() + .format(envlogger_write_format) + .init(); + Ok(()) +} + pub fn envlogger_write_format(buf: &mut Formatter, rec: &Record) -> io::Result<()> { let level_string = format!("{}", rec.level()); let level_style = buf.default_level_style(rec.level()); diff --git a/src/main.rs b/src/main.rs index 82afbcc..ce25cc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,6 @@ use std::error::Error; use axum::Router; -use dotenvy::var; -use log::LevelFilter; use sqlx::PgPool; use tokio::net::TcpListener; @@ -17,9 +15,6 @@ mod tags; mod users; mod web; -/// Mnemosyne, the mother of the nine muses -const DEFAULT_PORT: u16 = 0x9999; // 39321 - /// The string to be returned alongside HTTP 500 const ISE_MSG: &str = "Internal server error"; @@ -30,31 +25,16 @@ pub struct MnemoState { #[tokio::main] async fn main() -> Result<(), Box> { - if let Err(e) = dotenvy::dotenv() - && !e.not_found() - { - return Err(e.into()); - } - env_logger::builder() - .filter_level(LevelFilter::Info) - .filter_module("sqlx", LevelFilter::Warn) - .parse_default_env() - .format(config::envlogger_write_format) - .init(); + config::dotenv()?; + config::env_logger()?; - let pool = PgPool::connect(var("DATABASE_URL")?.as_str()).await?; + let pool = config::init_pool().await?; sqlx::migrate!("src/database/migrations").run(&pool).await?; log::info!("Migrations applied successfully."); users::auth::init_password_dummies(); users::setup::initialise_reserved_users_if_needed(&pool).await?; - let port = match std::env::var("PORT") { - Ok(p) => p.parse::()?, - Err(e) => match e { - std::env::VarError::NotPresent => DEFAULT_PORT, - _ => return Err(e)?, - }, - }; + let port = config::port()?; let r = Router::new() .merge(api::api_router()) .merge(web::web_router())