Files
slimes-website/src/main.rs
2026-05-07 23:19:22 +02:00

100 lines
2.5 KiB
Rust

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<T> {
pub data: T,
pub updated_at: Instant,
}
struct AppState {
app_name: String,
pub reports_cache: RwLock<Option<Cache<Vec<Report>>>>,
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(())
}