#![warn(clippy::all, clippy::pedantic, clippy::nursery)] #![allow(clippy::missing_docs_in_private_items)] mod config; mod models; mod routes; mod state; mod utils; use axum::serve; use clap::Parser; use log::info; use log4rs::config::Deserializers; use std::net::SocketAddr; use tokio::net::TcpListener; use utils::shutdown_signal; use config::Args; use state::State; #[tokio::main] async fn main() { let args = Args::parse(); log4rs::init_file(&args.log_config, Deserializers::default()).unwrap(); let state = State::from_args(args).await.unwrap(); sqlx::migrate!("./migrations") .run(&state.pg_pool) .await .expect("Failed to run migrations"); let routes = routes::routes(state.clone()); let app = axum::Router::new().nest(&format!("{}/api", state.config.server.subpath), routes); let addr = SocketAddr::from((state.config.server.address, state.config.server.port)); let listener = TcpListener::bind(addr).await.unwrap(); info!("Listening on {}", listener.local_addr().unwrap()); serve(listener, app) .with_graceful_shutdown(shutdown_signal()) .await .unwrap(); }