use axum::{Router, routing::get}; use clap::Parser; use fluent_templates::FluentLoader; use lazy_static::lazy_static; use std::{ sync::Arc, time::{Duration, Instant}, }; use tera::Tera; use tokio::sync::RwLock; mod handlers; use handlers::home_handler; mod i18n; use crate::{ handlers::{Report, analytics_handler, report_details_handler, set_lang_handler}, i18n::LOCALES, }; lazy_static! { pub static ref TEMPLATES: Tera = { let mut tera = Tera::default(); tera.add_raw_templates(vec![ ("_layout.html", include_str!("../templates/_layout.html")), ("_base.css", include_str!("../templates/_base.css")), ("index.html", include_str!("../templates/homepage.html")), ("details.html", include_str!("../templates/details.html")), ( "analytics.html", include_str!("../templates/analytics.html"), ), ]) .unwrap(); tera.register_function("fluent", FluentLoader::new(&*LOCALES)); tera }; } #[derive(clap::Parser, Debug)] #[command(author, version, about, long_about = None)] pub struct Cli { /// Port to serve on #[arg(short, long, default_value = "8000")] port: String, /// Whether to listen on 0.0.0.0 #[arg(long)] host: bool, /// Verbose mode #[arg(short, long)] verbose: bool, } pub struct Cache { pub data: T, pub updated_at: Instant, } struct AppState { app_name: String, pub reports_cache: RwLock>>>, pub cache_duration: Duration, } #[tokio::main] async fn main() -> anyhow::Result<()> { let cli = Cli::parse(); tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .init(); let shared_state = Arc::new(AppState { app_name: "Slimes Leaderboards".to_string(), reports_cache: RwLock::new(None), cache_duration: Duration::from_secs(30), }); let app = Router::new() .route("/", get(home_handler)) .route("/report/{id}", get(report_details_handler)) .route("/analytics", get(analytics_handler)) .route("/set-lang/{lang}", get(set_lang_handler)) .with_state(shared_state); let addr = if cli.host { format!("0.0.0.0:{}", cli.port) } else { format!("127.0.0.1:{}", cli.port) }; let listener = tokio::net::TcpListener::bind(&addr).await?; tracing::info!("Listening on http://{}", addr); axum::serve(listener, app).await?; Ok(()) }