mod config; mod state; mod middleware; mod handlers; use axum::{ routing::any, Router, middleware as axum_middleware, }; use axum_server::tls_rustls::RustlsConfig; use std::net::SocketAddr; use std::sync::Arc; use std::fs; use crate::config::Config; use crate::state::AppState; use crate::handlers::{handler, fallback_handler}; use crate::middleware::logging_middleware; use colored::*; #[tokio::main] async fn main() -> Result<(), Box> { // 1. Initial load to check for files and get host/port let config = Config::load(); // Ensure initial response files exist for route in &config.routes { if !route.response_file.exists() { println!("Response file {:?} not found, creating default.", route.response_file); let default_response = serde_json::json!({ "message": format!("edit me for path {}", route.path) }); fs::write(&route.response_file, serde_json::to_string_pretty(&default_response)?)?; } } // Print custom startup banner print_banner(&config); // 2. Prepare application state let state = Arc::new(AppState {}); // 3. Build router with a catch-all route for live config reloading let app = Router::new() .route("/", any(handler)) .route("/*path", any(handler)) .fallback(fallback_handler) .layer(axum_middleware::from_fn_with_state(state.clone(), logging_middleware)) .with_state(state); let addr: SocketAddr = format!("{}:{}", config.host, config.port).parse()?; // 4. Start server if config.tls.enabled { let tls_config = RustlsConfig::from_pem_file( config.tls.cert_path.clone(), config.tls.key_path.clone(), ) .await?; println!("Starting server with TLS on {}", addr); axum_server::bind_rustls(addr, tls_config) .serve(app.into_make_service()) .await?; } else { println!("Starting server on {}", addr); axum_server::bind(addr) .serve(app.into_make_service()) .await?; } Ok(()) } fn print_banner(config: &Config) { println!("{}", "------------------------------------------".bright_black()); println!("{}", " ____ ___ _ ______________ ".blue().bold()); println!("{}", " / __ |/ | / | / / _/ ____/ / ".blue().bold()); println!("{}", " / / / / /| | / |/ // // __/ / / ".blue().bold()); println!("{}", " / /_/ / ___ |/ /| // // /___/ /___ ".blue().bold()); println!("{}", " /_____/_/ |_/_/ |_/___/_____/_____/ ".blue().bold()); println!(" "); println!("{}", "Config: ".bold().underline()); println!(" "); println!("{:<14}: {}", "host".bright_black(), config.host.yellow()); println!("{:<14}: {}", "port".bright_black(), config.port.to_string().yellow()); println!("{:<14}: {}", "Live Reload".bright_black(), "ENABLED".green().bold()); println!("{}", "------------------------------------------".bright_black()); }