Move config into module and improve error handling

This commit is contained in:
Matthew Gordon 2024-02-12 21:38:36 -04:00
parent efc04fa8e5
commit 3402cb799d
2 changed files with 57 additions and 8 deletions

26
src/config.rs Normal file
View File

@ -0,0 +1,26 @@
use {std::env, thiserror::Error};
const ENV_VAR_PREFIX: &str = "LOCALHUB_";
#[derive(Error, Debug)]
pub enum Error {
#[error("The environment variable \"{0}\" must be set.")]
MissingEnvironmentVariable(String),
}
pub struct Config {
pub database_url: String,
pub static_file_path: String,
}
fn get_config_string(variable: &str) -> Result<String, Error> {
let full_var = format!("{ENV_VAR_PREFIX}{variable}");
env::var(&full_var).map_err(|_| Error::MissingEnvironmentVariable(full_var))
}
pub fn get_config() -> Result<Config, Error> {
Ok(Config {
database_url: get_config_string("DATABASE_URL")?,
static_file_path: get_config_string("STATIC_FILE_PATH")?,
})
}

View File

@ -1,24 +1,47 @@
use { use {
askama::Template, askama::Template,
axum::{extract::State, routing::get, Router}, axum::{extract::State, routing::get, Router},
std::env, thiserror::Error,
tower_http::services::ServeDir, tower_http::services::ServeDir,
}; };
mod config;
mod db; mod db;
use config::get_config;
use db::Database; use db::Database;
#[tokio::main] #[derive(Error, Debug)]
async fn main() -> Result<(), Box<dyn std::error::Error>> { pub enum Error {
let db_pool = Database::create_pool(&env::var("LOCALHUB_DATABASE_URL")?, 2)?; #[error("Loading configuration: \"{0}\"")]
MissingConfigError(#[from] config::Error),
#[error("Database error: {0}")]
DatabaseError(#[from] db::Error),
#[error("{0}")]
IOError(#[from] std::io::Error),
}
fn main() {
let runtime = tokio::runtime::Runtime::new().unwrap();
std::process::exit(match runtime.block_on(localhub_main()) {
Ok(()) => 0,
Err(err) => {
eprintln!("ERROR: {}", err);
1},
})
}
async fn localhub_main() -> Result<(), Error> {
let config = get_config()?;
let db_pool = Database::create_pool(&config.database_url, 2)?;
let app = Router::new() let app = Router::new()
.route("/", get(root)) .route("/", get(root))
.with_state(db_pool) .with_state(db_pool)
.nest_service( .nest_service("/static", ServeDir::new(&config.static_file_path));
"/static",
ServeDir::new(env::var("LOCALHUB_STATIC_FILE_PATH")?),
);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?; let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
axum::serve(listener, app).await?; axum::serve(listener, app).await?;