use { thiserror::Error, tower_http::{services::ServeDir, trace::TraceLayer}, tracing::Level, }; mod admin; mod app; mod authentication; mod config; mod db; mod error; use config::get_config; use db::{Database, PostgresDatabase}; #[derive(Error, Debug)] pub enum Error { #[error("Loading configuration: \"{0}\"")] MissingConfigError(#[from] config::Error), #[error("Database error: {0}")] DatabaseError(#[from] db::InitialisationError), #[error("{0}")] IOError(#[from] std::io::Error), #[error("{0}")] TracingError(#[from] tracing::subscriber::SetGlobalDefaultError), } fn main() { let runtime = tokio::runtime::Runtime::new().unwrap(); std::process::exit(match runtime.block_on(locality_main()) { Ok(()) => 0, Err(err) => { eprintln!("ERROR: {}", err); 1 } }) } async fn locality_main() -> Result<(), Error> { let config = get_config()?; let subscriber = tracing_subscriber::FmtSubscriber::builder() .pretty() .with_max_level(Level::DEBUG) .finish(); tracing::subscriber::set_global_default(subscriber)?; let db_pool = PostgresDatabase::new(&config.database_url)?; db_pool.migrate_to_current_version().await.unwrap(); let app = app::routes() .nest("/admin", admin::routes()) .with_state(app::AppState { db: db_pool }) .nest_service("/static", ServeDir::new(&config.static_file_path)) .layer(TraceLayer::new_for_http()); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?; axum::serve(listener, app).await?; Ok(()) }