From 36b0c0343da095efa17d502e27bf862c02283f45 Mon Sep 17 00:00:00 2001 From: ErrorNoInternet Date: Mon, 1 Jun 2026 20:53:20 -0400 Subject: [PATCH] treewide: set up formatting --- rustfmt.toml | 2 + src/main.rs | 206 +++++++++++++++++++-------------------------------- 2 files changed, 79 insertions(+), 129 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 218e203..157ed0b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,3 @@ +brace_style = "AlwaysNextLine" +control_brace_style = "AlwaysNextLine" hard_tabs = true diff --git a/src/main.rs b/src/main.rs index 47bf080..9bad49d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ // TODO rename pingscores userscores -use std:: -{ +use std::{ collections::HashMap, fs, io::Write, @@ -8,28 +7,25 @@ use std:: sync::Arc, }; -use axum:: -{ +use axum::{ Router, - extract:: - { + extract::{ State, ws::{Message, WebSocket, WebSocketUpgrade}, }, response::IntoResponse, routing::get, }; -use tokio:: -{ +use futures::StreamExt as _; +use rand::random_bool; +use regex::Regex; +use serde::{Deserialize, Serialize, de}; +use serde_json::json; +use tokio::{ sync::{Mutex, mpsc}, time::{Duration, sleep}, }; use tower_http::services::ServeDir; -use futures::StreamExt as _; -use rand::random_bool; -use serde::{Deserialize, Serialize, de}; -use serde_json::json; -use regex::Regex; #[derive(Deserialize, Serialize, Debug, Ord, Eq, PartialEq, PartialOrd, Clone)] struct Entry @@ -55,8 +51,14 @@ struct LeaderboardUpdate enum LeaderboardUpdateType { - Reset { hiscore_pingscore: u32 }, - Increment { loscore: u32 }, + Reset + { + hiscore_pingscore: u32 + }, + Increment + { + loscore: u32 + }, } const CHANCE: f64 = 1.0 / 3.0; @@ -70,11 +72,8 @@ const MAX_LEADERBOARD: usize = 20; #[tokio::main] async fn main() -> anyhow::Result<()> { - fn read_file de::Deserialize<'de>> - ( - file_path: &str, - ) - -> anyhow::Result>> + fn read_file de::Deserialize<'de>>(file_path: &str) + -> anyhow::Result>> { let file_contents: String = fs::read_to_string(file_path)?; Ok(Arc::new(Mutex::new(serde_json::from_str(&file_contents)?))) @@ -101,16 +100,14 @@ async fn main() -> anyhow::Result<()> { let (hiscores, loscores, pingscores) = (hiscores.clone(), loscores.clone(), pingscores.clone()); - tokio::spawn - (async move { + tokio::spawn(async move { handle_hiscores(rx, &hiscores, &loscores, &pingscores).await; }); } { let pingscores = pingscores.clone(); - tokio::spawn - (async move { + tokio::spawn(async move { // write pingscores every 30s loop { @@ -136,8 +133,7 @@ async fn main() -> anyhow::Result<()> .fallback_service(static_files) .route("/ws", get(ws_handler)) .route("/ws-leaderboard", get(leaderboard_handler)) - .with_state - (AppState { + .with_state(AppState { tx, hiscores: Arc::clone(&hiscores), loscores: Arc::clone(&loscores), @@ -153,34 +149,29 @@ async fn main() -> anyhow::Result<()> Ok(()) } // receiver: 0 for hiscore, 1 for loscore, 2 for pingscore -async fn handle_hiscores -( +async fn handle_hiscores( mut rx: mpsc::Receiver, hiscores: &Mutex>, loscores: &Mutex>, pingscores: &Mutex>, ) { - fn update_scoretable> + DerefMut> - ( + fn update_scoretable> + DerefMut>( score_name: &str, mut scoretable_lock: G, name: &str, score: u32, file_path: &str, - ) - -> anyhow::Result<()> + ) -> anyhow::Result<()> { let scoretable = &mut *scoretable_lock; if let Some(index_to_insert_at) = scoretable.iter().position(|e| score > e.score) { println!("New {score_name} {score} by {name}"); scoretable[index_to_insert_at..].rotate_right(1); - let push_out = std::mem::replace - ( + let push_out = std::mem::replace( &mut scoretable[index_to_insert_at], - Entry - { + Entry { score, person: name.to_string(), }, @@ -202,8 +193,7 @@ async fn handle_hiscores else if scoretable.len() < MAX_LEADERBOARD { println!("New {score_name} {score} by {name}"); - scoretable.push - (Entry { + scoretable.push(Entry { score, person: name.to_string(), }); @@ -237,8 +227,7 @@ async fn handle_hiscores LeaderboardUpdateType::Reset { hiscore_pingscore } => { // Hiscore - update_scoretable - ( + update_scoretable( "hiscore", hiscores.lock().await, &name, @@ -261,8 +250,7 @@ async fn handle_hiscores LeaderboardUpdateType::Increment { loscore } => { - update_scoretable - ( + update_scoretable( "loscore", loscores.lock().await, &name, @@ -275,27 +263,16 @@ async fn handle_hiscores } } -async fn leaderboard_handler -( +async fn leaderboard_handler( ws: WebSocketUpgrade, - State(state): State -) --> impl IntoResponse + State(state): State, +) -> impl IntoResponse { - ws.on_upgrade - (|socket| async move { - handle_leaderboard - ( - socket, - &state.hiscores, - &state.loscores, - &state.pingscores, - ) - .await; + ws.on_upgrade(|socket| async move { + handle_leaderboard(socket, &state.hiscores, &state.loscores, &state.pingscores).await; }) } -async fn handle_leaderboard -( +async fn handle_leaderboard( mut socket: WebSocket, hiscores: &Mutex>, loscores: &Mutex>, @@ -306,82 +283,57 @@ async fn handle_leaderboard { Some(Ok(Message::Text(selection))) => { - let msg; - match selection.as_str() + let msg = match selection.as_str() { - "0" => // all the leaderboards - { - msg = - { - json! - ({ - "hiscores": &*hiscores.lock().await, - "loscores": &*loscores.lock().await, - "pingscores": &*pingscores.lock().await - }) - .to_string() - }; - }, - "1" => // just the hiscores table - { - msg = json! ({ "hiscores": &*hiscores.lock().await }).to_string() - }, - "2" => // just the loscores table - { - msg = json! ({ "loscores": &*hiscores.lock().await }).to_string() - }, - "3" => // just the pingscores table - { - msg = json! ({ "pingscores": &*hiscores.lock().await }).to_string() - }, - _ => { msg = "Invalid leaderboard selection, please use 0,1,2 or 3".to_string() }, - } + // all the leaderboards + "0" => json! + ({ + "hiscores": &*hiscores.lock().await, + "loscores": &*loscores.lock().await, + "pingscores": &*pingscores.lock().await + }) + .to_string(), + // just the hiscores table + "1" => json! ({ "hiscores": &*hiscores.lock().await }).to_string(), + // just the loscores table + "2" => json! ({ "loscores": &*hiscores.lock().await }).to_string(), + // just the pingscores table + "3" => json! ({ "pingscores": &*hiscores.lock().await }).to_string(), + _ => "Invalid leaderboard selection, please use 0,1,2 or 3".to_string(), + }; let _ = socket.send(Message::Text(msg.into())).await; - }, + } _ => { - let _ = socket.send(Message::Text("Invalid leaderboard selection, please use 0,1,2 or 3".into())).await; - }, + let _ = socket + .send(Message::Text( + "Invalid leaderboard selection, please use 0,1,2 or 3".into(), + )) + .await; + } } } -async fn ws_handler -( - ws: WebSocketUpgrade, - State(state): State -) - -> impl IntoResponse +async fn ws_handler(ws: WebSocketUpgrade, State(state): State) -> impl IntoResponse { - ws.on_upgrade - (|socket| async move { - handle_socket - ( - socket, - &state.tx, - ) - .await; + ws.on_upgrade(|socket| async move { + handle_socket(socket, &state.tx).await; }) } -async fn handle_socket -( - mut socket: WebSocket, - tx: &mpsc::Sender, -) +async fn handle_socket(mut socket: WebSocket, tx: &mpsc::Sender) { let mut value: u32 = 0; - let Some(name) = socket.next().await else + let Some(name) = socket.next().await + else { eprintln!("No username"); return; }; let name: Arc = match name.expect("failed to recv socket msg") { - Message::Text(text) => - { - Arc::from(validate_name(&text)) - } + Message::Text(text) => Arc::from(validate_name(&text)), _ => Arc::from("anon"), }; @@ -401,11 +353,9 @@ async fn handle_socket { // reset let _ = tx - .send(LeaderboardUpdate - { + .send(LeaderboardUpdate { name: name.clone(), - update: LeaderboardUpdateType::Reset - { + update: LeaderboardUpdateType::Reset { hiscore_pingscore: value, }, }) @@ -419,8 +369,7 @@ async fn handle_socket if prev == 0 { let _ = tx - .send - (LeaderboardUpdate { + .send(LeaderboardUpdate { name: name.clone(), update: LeaderboardUpdateType::Increment { loscore: resets }, }) @@ -437,28 +386,27 @@ async fn handle_socket break; } - _ => {} + _ => + {} } } } -fn validate_name(input: &str) -> &str { +fn validate_name(input: &str) -> &str +{ let input = input.trim(); if input == "null" { return "anon"; } // Length check - if input.is_empty() || input.len() > 32 { + if input.is_empty() || input.len() > 32 + { return "anon"; } // Allow only letters, numbers, _ and - let re = Regex::new(r"^[a-zA-Z0-9_-]+$").unwrap(); - if re.is_match(input) { - input - } else { - "anon" - } + if re.is_match(input) { input } else { "anon" } }