use std::sync::Arc; use mikebase::{config::AppConfig, db::Database, storage::S3Storage, AppState, build_router}; use sqlx::any::install_default_drivers; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[tokio::main] async fn main() { // Initialise structured logging. tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| "mikebase=debug,tower_http=debug".into()), ) .with(tracing_subscriber::fmt::layer()) .init(); // Load configuration from config.toml / environment variables. let cfg = AppConfig::load().expect("Failed to load configuration"); let cfg = Arc::new(cfg); // Install SQLite and PostgreSQL drivers for sqlx AnyPool. install_default_drivers(); // Connect to the database and run migrations. let db = Database::connect(&cfg.database.url) .await .expect("Failed to connect to database"); db.migrate().await.expect("Failed to run migrations"); // Build S3 storage client. let storage = S3Storage::new(&cfg); let state = AppState { db, storage, cfg: cfg.clone() }; let addr = format!("{}:{}", cfg.server.host, cfg.server.port); tracing::info!("Listening on {addr}"); let listener = tokio::net::TcpListener::bind(&addr) .await .expect("Failed to bind address"); axum::serve(listener, build_router(state)) .await .expect("Server error"); }