From 2fb835200ffb7c176d07bad0b40078c609dc83d6 Mon Sep 17 00:00:00 2001 From: funman300 Date: Thu, 20 Aug 2026 17:59:02 +0000 Subject: [PATCH] style(core): cargo fmt match/club agent additions --- src/services/achievement.rs | 119 +++++++++++++++++----------------- src/services/club.rs | 22 +++---- src/services/match_service.rs | 48 +++++++++++--- src/services/objective.rs | 2 +- 4 files changed, 108 insertions(+), 83 deletions(-) diff --git a/src/services/achievement.rs b/src/services/achievement.rs index 0cd8707..d1f687e 100644 --- a/src/services/achievement.rs +++ b/src/services/achievement.rs @@ -5,10 +5,10 @@ use crate::{ services::{club as club_svc, notification}, }; use anyhow::Context; -use std::path::Path; -use uuid::Uuid; use sqlx::{Sqlite, Transaction}; use std::collections::{HashMap, HashSet}; +use std::path::Path; +use uuid::Uuid; pub fn load_achievement_definitions(data_dir: &str) -> anyhow::Result> { let dir = Path::new(data_dir).join("achievements"); @@ -196,67 +196,68 @@ async fn metric_value_tx( club_id: &str, trigger: &str, ) -> AppResult { - let v: i64 = match trigger { - "matches_played" => { - sqlx::query_scalar("SELECT matches_played FROM statistics WHERE profile_id = ?") + let v: i64 = + match trigger { + "matches_played" => { + sqlx::query_scalar("SELECT matches_played FROM statistics WHERE profile_id = ?") + .bind(profile_id) + .fetch_optional(&mut **tx) + .await? + .unwrap_or(0) + } + "matches_won" => { + sqlx::query_scalar("SELECT matches_won FROM statistics WHERE profile_id = ?") + .bind(profile_id) + .fetch_optional(&mut **tx) + .await? + .unwrap_or(0) + } + "goals_scored" => { + sqlx::query_scalar("SELECT goals_scored FROM statistics WHERE profile_id = ?") + .bind(profile_id) + .fetch_optional(&mut **tx) + .await? + .unwrap_or(0) + } + "packs_opened" => { + sqlx::query_scalar("SELECT packs_opened FROM statistics WHERE profile_id = ?") + .bind(profile_id) + .fetch_optional(&mut **tx) + .await? + .unwrap_or(0) + } + "sbcs_completed" => { + sqlx::query_scalar("SELECT sbcs_completed FROM statistics WHERE profile_id = ?") + .bind(profile_id) + .fetch_optional(&mut **tx) + .await? + .unwrap_or(0) + } + "cards_owned" => { + sqlx::query_scalar("SELECT COUNT(*) FROM owned_cards WHERE club_id = ?") + .bind(club_id) + .fetch_one(&mut **tx) + .await? + } + "level" => sqlx::query_scalar("SELECT level FROM profiles WHERE id = ?") .bind(profile_id) .fetch_optional(&mut **tx) .await? - .unwrap_or(0) - } - "matches_won" => { - sqlx::query_scalar("SELECT matches_won FROM statistics WHERE profile_id = ?") - .bind(profile_id) - .fetch_optional(&mut **tx) - .await? - .unwrap_or(0) - } - "goals_scored" => { - sqlx::query_scalar("SELECT goals_scored FROM statistics WHERE profile_id = ?") - .bind(profile_id) - .fetch_optional(&mut **tx) - .await? - .unwrap_or(0) - } - "packs_opened" => { - sqlx::query_scalar("SELECT packs_opened FROM statistics WHERE profile_id = ?") - .bind(profile_id) - .fetch_optional(&mut **tx) - .await? - .unwrap_or(0) - } - "sbcs_completed" => { - sqlx::query_scalar("SELECT sbcs_completed FROM statistics WHERE profile_id = ?") - .bind(profile_id) - .fetch_optional(&mut **tx) - .await? - .unwrap_or(0) - } - "cards_owned" => { - sqlx::query_scalar("SELECT COUNT(*) FROM owned_cards WHERE club_id = ?") - .bind(club_id) - .fetch_one(&mut **tx) - .await? - } - "level" => sqlx::query_scalar("SELECT level FROM profiles WHERE id = ?") + .unwrap_or(1), + "objectives_completed" => sqlx::query_scalar( + "SELECT COUNT(*) FROM objective_progress WHERE profile_id = ? AND completed = 1", + ) .bind(profile_id) - .fetch_optional(&mut **tx) - .await? - .unwrap_or(1), - "objectives_completed" => sqlx::query_scalar( - "SELECT COUNT(*) FROM objective_progress WHERE profile_id = ? AND completed = 1", - ) - .bind(profile_id) - .fetch_one(&mut **tx) - .await?, - "drafts_completed" => sqlx::query_scalar( - "SELECT COUNT(*) FROM draft_sessions WHERE profile_id = ? AND status = 'completed'", - ) - .bind(profile_id) - .fetch_one(&mut **tx) - .await?, - _ => 0, - }; + .fetch_one(&mut **tx) + .await?, + "drafts_completed" => sqlx::query_scalar( + "SELECT COUNT(*) FROM draft_sessions WHERE profile_id = ? AND status = 'completed'", + ) + .bind(profile_id) + .fetch_one(&mut **tx) + .await?, + _ => 0, + }; Ok(v) } diff --git a/src/services/club.rs b/src/services/club.rs index 8c95b74..38cdda2 100644 --- a/src/services/club.rs +++ b/src/services/club.rs @@ -140,14 +140,12 @@ const OWNED_SELECT: &str = "SELECT id, club_id, card_id, is_loan, loan_matches_r /// The club's most-recently-updated squad id (its "active" squad), matching the /// selection `squad::get_squad` uses, or `None` when the club has no squad yet. pub async fn active_squad_id(pool: &Pool, club_id: &str) -> AppResult> { - Ok( - sqlx::query_scalar::<_, String>( - "SELECT id FROM squads WHERE club_id = ? ORDER BY updated_at DESC LIMIT 1", - ) - .bind(club_id) - .fetch_optional(pool) - .await?, + Ok(sqlx::query_scalar::<_, String>( + "SELECT id FROM squads WHERE club_id = ? ORDER BY updated_at DESC LIMIT 1", ) + .bind(club_id) + .fetch_optional(pool) + .await?) } /// The owned card assigned as the manager of `club_id`'s active squad, if any. @@ -182,11 +180,7 @@ pub async fn get_squad_manager_for_squad( /// belong to `club_id`, so a client can neither manage another club's squad nor /// assign a card it does not own. One manager per squad (the PK REPLACE), so a /// re-assignment never accumulates duplicate rows. -pub async fn set_squad_manager( - pool: &Pool, - club_id: &str, - owned_card_id: &str, -) -> AppResult<()> { +pub async fn set_squad_manager(pool: &Pool, club_id: &str, owned_card_id: &str) -> AppResult<()> { let squad_id = active_squad_id(pool, club_id) .await? .ok_or_else(|| AppError::NotFound("club has no squad to assign a manager to".into()))?; @@ -304,7 +298,9 @@ mod tests { let (dir, url, pool) = fixture().await; // SAVE. - set_squad_manager(&pool, "club-a", "mgr").await.expect("assign"); + set_squad_manager(&pool, "club-a", "mgr") + .await + .expect("assign"); // RELOAD (same pool). let got = get_squad_manager(&pool, "club-a").await.unwrap(); assert_eq!(got.as_ref().map(|c| c.id.as_str()), Some("mgr")); diff --git a/src/services/match_service.rs b/src/services/match_service.rs index da4e45f..0172292 100644 --- a/src/services/match_service.rs +++ b/src/services/match_service.rs @@ -438,7 +438,9 @@ async fn complete_match_inner( )); } if req.match_identity.trim().is_empty() { - return Err(AppError::BadRequest("match_identity must not be empty".into())); + return Err(AppError::BadRequest( + "match_identity must not be empty".into(), + )); } let result = req.result; @@ -905,7 +907,11 @@ mod match_completion_tests { assert_eq!(r.xp_awarded, XP_LOSS); assert_eq!(r.match_record.outcome, "dnf"); assert_eq!(stat(&fx.pool, "matches_dnf").await, 1); - assert_eq!(stat(&fx.pool, "matches_lost").await, 0, "DNF is not a loss row"); + assert_eq!( + stat(&fx.pool, "matches_lost").await, + 0, + "DNF is not a loss row" + ); assert_eq!(stat(&fx.pool, "matches_played").await, 1); assert_eq!(coins(&fx.pool).await, START_COINS + COINS_LOSS); } @@ -922,7 +928,11 @@ mod match_completion_tests { assert_eq!(r.match_record.outcome, "no_contest"); assert_eq!(coins(&fx.pool).await, START_COINS, "no coins for a void"); assert_eq!(xp(&fx.pool).await, 0); - assert_eq!(stat(&fx.pool, "matches_played").await, 0, "not counted as played"); + assert_eq!( + stat(&fx.pool, "matches_played").await, + 0, + "not counted as played" + ); // Still recorded for history + idempotency. assert_eq!(count(&fx.pool, "matches").await, 1); assert_eq!(count(&fx.pool, "match_completions").await, 1); @@ -1089,7 +1099,11 @@ mod match_completion_tests { .await .unwrap(); assert!(retry.applied, "{fp:?} retry-after-fault must apply"); - assert_eq!(coins(&fx.pool).await, START_COINS + COINS_WIN, "{fp:?} retry"); + assert_eq!( + coins(&fx.pool).await, + START_COINS + COINS_WIN, + "{fp:?} retry" + ); } } @@ -1129,9 +1143,16 @@ mod match_completion_tests { ]; let achs = vec![ach("first_win", "matches_won", 1, 50)]; - let first = complete_match(&fx.pool, PROFILE, CLUB, &req("m", MatchResultKind::Win, 2, 0), &objs, &achs) - .await - .unwrap(); + let first = complete_match( + &fx.pool, + PROFILE, + CLUB, + &req("m", MatchResultKind::Win, 2, 0), + &objs, + &achs, + ) + .await + .unwrap(); assert!(first.applied); assert_eq!(first.objectives_updated.len(), 2); assert_eq!(first.achievements_unlocked.len(), 1); @@ -1140,9 +1161,16 @@ mod match_completion_tests { assert_eq!(count(&fx.pool, "player_achievements").await, 1); // Replay: no double objectives/achievements/coins. - let replay = complete_match(&fx.pool, PROFILE, CLUB, &req("m", MatchResultKind::Win, 2, 0), &objs, &achs) - .await - .unwrap(); + let replay = complete_match( + &fx.pool, + PROFILE, + CLUB, + &req("m", MatchResultKind::Win, 2, 0), + &objs, + &achs, + ) + .await + .unwrap(); assert!(!replay.applied); assert!(replay.objectives_updated.is_empty()); assert!(replay.achievements_unlocked.is_empty()); diff --git a/src/services/objective.rs b/src/services/objective.rs index 0ed203a..87c4629 100644 --- a/src/services/objective.rs +++ b/src/services/objective.rs @@ -6,9 +6,9 @@ use crate::{ }, }; use anyhow::Context; +use sqlx::{Sqlite, Transaction}; use std::path::Path; use uuid::Uuid; -use sqlx::{Sqlite, Transaction}; pub fn load_objective_definitions(data_dir: &str) -> anyhow::Result> { let dir = Path::new(data_dir).join("objectives");