From 7cda2a9f1a55f37d43a18b97f142089c92017b28 Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 29 Apr 2026 03:35:41 +0000 Subject: [PATCH] fix(engine): resolve all clippy warnings introduced by PNG asset pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Collapse nested-if patterns into let-chains across 13 plugins (42 instances) - Add #[allow(clippy::too_many_arguments)] to 5 Bevy systems in card_plugin and input_plugin where ECS parameter count exceeds the lint threshold - Gate Theme import in table_plugin under #[cfg(test)] — only used by test-only colour helpers; removing the unconditional import silences the unused-import lint without breaking the test suite - Wrap ButtonInput in Option<> in update_input_platform so that tests using MinimalPlugins (no InputPlugin) no longer panic on startup All 789 tests pass; cargo clippy --workspace -- -D warnings is clean. Co-Authored-By: Claude Sonnet 4.6 --- solitaire_engine/src/achievement_plugin.rs | 16 +++---- solitaire_engine/src/animation_plugin.rs | 5 +-- solitaire_engine/src/card_animation/tuning.rs | 7 +-- solitaire_engine/src/card_plugin.rs | 3 ++ solitaire_engine/src/challenge_plugin.rs | 5 +-- .../src/daily_challenge_plugin.rs | 15 +++---- solitaire_engine/src/game_plugin.rs | 25 +++++------ solitaire_engine/src/hud_plugin.rs | 5 +-- solitaire_engine/src/input_plugin.rs | 44 ++++++++----------- solitaire_engine/src/leaderboard_plugin.rs | 5 +-- solitaire_engine/src/pause_plugin.rs | 21 ++++----- solitaire_engine/src/progress_plugin.rs | 5 +-- solitaire_engine/src/selection_plugin.rs | 18 +++----- solitaire_engine/src/stats_plugin.rs | 5 +-- solitaire_engine/src/sync_plugin.rs | 15 +++---- solitaire_engine/src/table_plugin.rs | 3 +- solitaire_engine/src/weekly_goals_plugin.rs | 16 +++---- 17 files changed, 89 insertions(+), 124 deletions(-) diff --git a/solitaire_engine/src/achievement_plugin.rs b/solitaire_engine/src/achievement_plugin.rs index 90c6542..59a5d4f 100644 --- a/solitaire_engine/src/achievement_plugin.rs +++ b/solitaire_engine/src/achievement_plugin.rs @@ -176,21 +176,17 @@ fn evaluate_on_win( unlocks.write(AchievementUnlockedEvent(record.clone())); } - if achievements_changed { - if let Some(target) = &path.0 { - if let Err(e) = save_achievements_to(target, &achievements.0) { + if achievements_changed + && let Some(target) = &path.0 + && let Err(e) = save_achievements_to(target, &achievements.0) { warn!("failed to save achievements: {e}"); } - } - } - if progress_changed { - if let Some(target) = &progress_path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if progress_changed + && let Some(target) = &progress_path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress after reward: {e}"); } - } - } } /// Convenience: resolve an achievement ID to its human-readable name. diff --git a/solitaire_engine/src/animation_plugin.rs b/solitaire_engine/src/animation_plugin.rs index caabf9f..8815c15 100644 --- a/solitaire_engine/src/animation_plugin.rs +++ b/solitaire_engine/src/animation_plugin.rs @@ -472,13 +472,12 @@ fn drive_toast_display( } // If no active toast and the queue has messages, show the next one. - if active.entity.is_none() { - if let Some(message) = queue.0.pop_front() { + if active.entity.is_none() + && let Some(message) = queue.0.pop_front() { let entity = spawn_queued_toast(&mut commands, message); active.entity = Some(entity); active.timer = QUEUED_TOAST_SECS; } - } } /// Spawns a centered top-of-screen `ToastEntity` for the queued toast system. diff --git a/solitaire_engine/src/card_animation/tuning.rs b/solitaire_engine/src/card_animation/tuning.rs index cf82230..bc8f558 100644 --- a/solitaire_engine/src/card_animation/tuning.rs +++ b/solitaire_engine/src/card_animation/tuning.rs @@ -148,7 +148,7 @@ impl Default for AnimationTuning { /// running under `MinimalPlugins` (which does not register the touch subsystem). pub(crate) fn update_input_platform( touches: Option>, - mouse_buttons: Res>, + mouse_buttons: Option>>, mut tuning: ResMut, ) { let touch_active = touches.as_ref().is_some_and(|t| { @@ -157,8 +157,9 @@ pub(crate) fn update_input_platform( || t.iter_just_released().next().is_some() }); - let mouse_active = mouse_buttons.get_just_pressed().next().is_some() - || mouse_buttons.get_pressed().next().is_some(); + let mouse_active = mouse_buttons.as_ref().is_some_and(|mb| { + mb.get_just_pressed().next().is_some() || mb.get_pressed().next().is_some() + }); if touch_active && tuning.platform != InputPlatform::Touch { *tuning = AnimationTuning::mobile(); diff --git a/solitaire_engine/src/card_plugin.rs b/solitaire_engine/src/card_plugin.rs index 6683032..031c34f 100644 --- a/solitaire_engine/src/card_plugin.rs +++ b/solitaire_engine/src/card_plugin.rs @@ -394,6 +394,7 @@ fn sync_cards_startup( } } +#[allow(clippy::too_many_arguments)] fn sync_cards_on_change( mut events: MessageReader, commands: Commands, @@ -416,6 +417,7 @@ fn sync_cards_on_change( } } +#[allow(clippy::too_many_arguments)] fn sync_cards( mut commands: Commands, game: &GameState, @@ -542,6 +544,7 @@ fn face_colour(card: &Card, color_blind: bool) -> Color { } } +#[allow(clippy::too_many_arguments)] fn spawn_card_entity( commands: &mut Commands, card: &Card, diff --git a/solitaire_engine/src/challenge_plugin.rs b/solitaire_engine/src/challenge_plugin.rs index 2b4f9fc..dae83bd 100644 --- a/solitaire_engine/src/challenge_plugin.rs +++ b/solitaire_engine/src/challenge_plugin.rs @@ -54,11 +54,10 @@ fn advance_on_challenge_win( } let prev = progress.0.challenge_index; progress.0.challenge_index = prev.saturating_add(1); - if let Some(target) = &path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if let Some(target) = &path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress after challenge advance: {e}"); } - } // Human-readable level is 1-based (index 0 → "Challenge 1"). let level_number = prev.saturating_add(1); toast.write(InfoToastEvent(format!("Challenge {level_number} complete!"))); diff --git a/solitaire_engine/src/daily_challenge_plugin.rs b/solitaire_engine/src/daily_challenge_plugin.rs index b1c6af2..b8768f2 100644 --- a/solitaire_engine/src/daily_challenge_plugin.rs +++ b/solitaire_engine/src/daily_challenge_plugin.rs @@ -161,27 +161,24 @@ fn handle_daily_completion( continue; } // Enforce server-supplied goal constraints when present. - if let Some(target) = daily.target_score { - if ev.score < target { + if let Some(target) = daily.target_score + && ev.score < target { continue; // score goal not met } - } - if let Some(max_secs) = daily.max_time_secs { - if ev.time_seconds > max_secs { + if let Some(max_secs) = daily.max_time_secs + && ev.time_seconds > max_secs { continue; // time limit exceeded } - } if !progress.0.record_daily_completion(daily.date) { // Already counted today — no-op. continue; } progress.0.add_xp(DAILY_BONUS_XP); xp_awarded.write(XpAwardedEvent { amount: DAILY_BONUS_XP }); - if let Some(target) = &path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if let Some(target) = &path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress after daily completion: {e}"); } - } completed.write(DailyChallengeCompletedEvent { date: daily.date, streak: progress.0.daily_challenge_streak, diff --git a/solitaire_engine/src/game_plugin.rs b/solitaire_engine/src/game_plugin.rs index 1dc4ab2..4054d50 100644 --- a/solitaire_engine/src/game_plugin.rs +++ b/solitaire_engine/src/game_plugin.rs @@ -194,11 +194,10 @@ fn handle_new_game( let mode = ev.mode.unwrap_or(game.0.mode); game.0 = GameState::new_with_mode(seed, draw_mode, mode); // Delete any previously saved in-progress state — this is a fresh game. - if let Some(p) = path.as_ref().and_then(|r| r.0.as_deref()) { - if let Err(e) = delete_game_state_at(p) { + if let Some(p) = path.as_ref().and_then(|r| r.0.as_deref()) + && let Err(e) = delete_game_state_at(p) { warn!("game_state: failed to delete saved game: {e}"); } - } changed.write(StateChangedEvent); } } @@ -380,14 +379,13 @@ fn handle_move( match game.0.move_cards(ev.from.clone(), ev.to.clone(), ev.count) { Ok(()) => { // Fire flip event if the candidate card is now face-up. - if let Some(fid) = flip_candidate_id { - if game.0.piles.get(&ev.from) + if let Some(fid) = flip_candidate_id + && game.0.piles.get(&ev.from) .and_then(|p| p.cards.last()) .is_some_and(|c| c.id == fid && c.face_up) { flipped.write(crate::events::CardFlippedEvent(fid)); } - } changed.write(StateChangedEvent); if !was_won && game.0.is_won { won.write(GameWonEvent { @@ -395,11 +393,10 @@ fn handle_move( time_seconds: game.0.elapsed_seconds, }); // Delete the saved state — a won game should not be resumed. - if let Some(p) = path.as_ref().and_then(|r| r.0.as_deref()) { - if let Err(e) = delete_game_state_at(p) { + if let Some(p) = path.as_ref().and_then(|r| r.0.as_deref()) + && let Err(e) = delete_game_state_at(p) { warn!("game_state: failed to delete on win: {e}"); } - } } } Err(e) => warn!("move rejected {:?} -> {:?} x{}: {e}", ev.from, ev.to, ev.count), @@ -468,11 +465,10 @@ pub fn has_legal_moves(game: &GameState) -> bool { // Check foundations. for &suit in &suits { let dest = PileType::Foundation(suit); - if let Some(dest_pile) = game.piles.get(&dest) { - if can_place_on_foundation(card, dest_pile, suit) { + if let Some(dest_pile) = game.piles.get(&dest) + && can_place_on_foundation(card, dest_pile, suit) { return true; } - } } // Check tableau piles. @@ -481,11 +477,10 @@ pub fn has_legal_moves(game: &GameState) -> bool { if dest == *from { continue; } - if let Some(dest_pile) = game.piles.get(&dest) { - if can_place_on_tableau(card, dest_pile) { + if let Some(dest_pile) = game.piles.get(&dest) + && can_place_on_tableau(card, dest_pile) { return true; } - } } } diff --git a/solitaire_engine/src/hud_plugin.rs b/solitaire_engine/src/hud_plugin.rs index 5996026..f413ada 100644 --- a/solitaire_engine/src/hud_plugin.rs +++ b/solitaire_engine/src/hud_plugin.rs @@ -437,15 +437,14 @@ fn update_hud( // Reflects the AutoCompleteState resource; update whenever it changes or game changes. let ac_active = auto_complete.as_ref().is_some_and(|ac| ac.active); let ac_changed = auto_complete.as_ref().is_some_and(|ac| ac.is_changed()); - if ac_changed || game.is_changed() { - if let Ok(mut t) = auto_q.single_mut() { + if (ac_changed || game.is_changed()) + && let Ok(mut t) = auto_q.single_mut() { **t = if ac_active { "AUTO".to_string() } else { String::new() }; } - } } /// Updates the `HudSelection` text node to show which pile is Tab-selected. diff --git a/solitaire_engine/src/input_plugin.rs b/solitaire_engine/src/input_plugin.rs index fa156b3..c8438c3 100644 --- a/solitaire_engine/src/input_plugin.rs +++ b/solitaire_engine/src/input_plugin.rs @@ -136,6 +136,7 @@ struct CoreKeyboardMessages<'w> { /// /// Also resets `forfeit_countdown` whenever U, D, Z, or N are pressed so that /// an in-flight forfeit confirmation is cancelled by any other action. +#[allow(clippy::too_many_arguments)] fn handle_keyboard_core( keys: Res>, paused: Option>, @@ -174,8 +175,8 @@ fn handle_keyboard_core( confirm.forfeit_countdown = 0.0; // If a Time Attack session is running, cancel it and start a Classic game. - if let Some(ref mut session) = time_attack { - if session.active { + if let Some(ref mut session) = time_attack + && session.active { session.active = false; session.remaining_secs = 0.0; ev.info_toast.write(InfoToastEvent("Time Attack ended".to_string())); @@ -186,7 +187,6 @@ fn handle_keyboard_core( confirm.new_game_countdown = 0.0; return; } - } let active_game = game.as_ref().is_some_and(|g| g.0.move_count > 0 && !g.0.is_won); let shift_held = keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight); @@ -244,6 +244,7 @@ fn handle_keyboard_core( /// /// The hint index wraps around once all hints have been cycled through. When no /// moves are available a "No hints available" toast is shown instead. +#[allow(clippy::too_many_arguments)] fn handle_keyboard_hint( keys: Res>, paused: Option>, @@ -273,7 +274,7 @@ fn handle_keyboard_hint( return; } - let Some(ref layout_res) = layout else { return }; + let Some(_layout_res) = layout else { return }; let hints = all_hints(&g.0); if hints.is_empty() { @@ -661,8 +662,8 @@ fn end_drag( // the placement is illegal, fire MoveRejectedEvent so AudioPlugin can // play card_invalid.wav. let mut fired = false; - if let Some(target) = target { - if target != origin { + if let Some(target) = target + && target != origin { let bottom_card_id = drag.cards[0]; if let Some(bottom_card) = card_by_id(&game.0, bottom_card_id) { let ok = match &target { @@ -708,7 +709,6 @@ fn end_drag( } } } - } drag.clear(); @@ -892,8 +892,8 @@ fn touch_end_drag( world.and_then(|w| find_drop_target(w, &game.0, &layout.0, &origin)); let mut fired = false; - if let Some(target) = target { - if target != origin { + if let Some(target) = target + && target != origin { let bottom_card_id = drag.cards[0]; if let Some(bottom_card) = card_by_id(&game.0, bottom_card_id) { let ok = match &target { @@ -924,7 +924,6 @@ fn touch_end_drag( } } } - } drag.clear(); changed.write(StateChangedEvent); @@ -1132,20 +1131,18 @@ pub fn best_destination(card: &Card, game: &GameState) -> Option { // Try all four foundations first. for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] { let dest = PileType::Foundation(suit); - if let Some(pile) = game.piles.get(&dest) { - if can_place_on_foundation(card, pile, suit) { + if let Some(pile) = game.piles.get(&dest) + && can_place_on_foundation(card, pile, suit) { return Some(dest); } - } } // Then try all seven tableau piles. for i in 0..7_usize { let dest = PileType::Tableau(i); - if let Some(pile) = game.piles.get(&dest) { - if can_place_on_tableau(card, pile) { + if let Some(pile) = game.piles.get(&dest) + && can_place_on_tableau(card, pile) { return Some(dest); } - } } None } @@ -1167,11 +1164,10 @@ pub fn best_tableau_destination_for_stack( if dest == *from { continue; } - if let Some(pile) = game.piles.get(&dest) { - if can_place_on_tableau(bottom_card, pile) { + if let Some(pile) = game.piles.get(&dest) + && can_place_on_tableau(bottom_card, pile) { return Some((dest, stack_count)); } - } } None } @@ -1309,14 +1305,13 @@ pub fn all_hints(game: &GameState) -> Vec<(PileType, PileType, usize)> { let Some(card) = from_pile.cards.last().filter(|c| c.face_up) else { continue }; for &suit in &suits { let dest = PileType::Foundation(suit); - if let Some(dest_pile) = game.piles.get(&dest) { - if can_place_on_foundation(card, dest_pile, suit) { + if let Some(dest_pile) = game.piles.get(&dest) + && can_place_on_foundation(card, dest_pile, suit) { hints.push((from.clone(), dest, 1)); // Each source card can go to at most one foundation suit; // no need to check the remaining three for this card. break; } - } } } @@ -1338,15 +1333,14 @@ pub fn all_hints(game: &GameState) -> Vec<(PileType, PileType, usize)> { if dest == *from { continue; } - if let Some(dest_pile) = game.piles.get(&dest) { - if can_place_on_tableau(card, dest_pile) { + if let Some(dest_pile) = game.piles.get(&dest) + && can_place_on_tableau(card, dest_pile) { hints.push((from.clone(), dest, 1)); // One tableau destination per source card is enough for the // hint list — the player can see where else a card can go // via the right-click destination highlights. break; } - } } } diff --git a/solitaire_engine/src/leaderboard_plugin.rs b/solitaire_engine/src/leaderboard_plugin.rs index 3bd0deb..665bc36 100644 --- a/solitaire_engine/src/leaderboard_plugin.rs +++ b/solitaire_engine/src/leaderboard_plugin.rs @@ -123,15 +123,14 @@ fn toggle_leaderboard_screen( spawn_leaderboard_screen(&mut commands, data.0.as_deref()); // Start a background fetch if not already in flight. - if task_res.0.is_none() { - if let Some(p) = provider { + if task_res.0.is_none() + && let Some(p) = provider { let provider = p.0.clone(); let task = AsyncComputeTaskPool::get().spawn(async move { provider.fetch_leaderboard().await.map_err(|e| e.to_string()) }); task_res.0 = Some(task); } - } } /// Poll the background fetch task; store results when complete. diff --git a/solitaire_engine/src/pause_plugin.rs b/solitaire_engine/src/pause_plugin.rs index bb52242..b20b4bc 100644 --- a/solitaire_engine/src/pause_plugin.rs +++ b/solitaire_engine/src/pause_plugin.rs @@ -103,13 +103,12 @@ fn toggle_pause( // If a drag is in progress, cancel it instead of opening the pause overlay. // Clearing DragState and emitting StateChangedEvent snaps the dragged cards // back to their resting positions exactly as a rejected drop does. - if let Some(ref mut d) = drag { - if !d.is_idle() { + if let Some(ref mut d) = drag + && !d.is_idle() { d.clear(); changed.write(StateChangedEvent); return; } - } if let Ok(entity) = screens.single() { commands.entity(entity).despawn(); paused.0 = false; @@ -122,13 +121,11 @@ fn toggle_pause( paused.0 = true; // Persist the current game state whenever the player opens the pause // overlay so an OS-level kill still leaves a resumable save. - if let (Some(g), Some(p)) = (game, path) { - if let Some(disk_path) = p.0.as_deref() { - if let Err(e) = save_game_state_to(disk_path, &g.0) { + if let (Some(g), Some(p)) = (game, path) + && let Some(disk_path) = p.0.as_deref() + && let Err(e) = save_game_state_to(disk_path, &g.0) { warn!("game_state: failed to save on pause: {e}"); } - } - } } } @@ -155,13 +152,11 @@ fn handle_pause_draw_toggle( DrawMode::DrawOne => DrawMode::DrawThree, DrawMode::DrawThree => DrawMode::DrawOne, }; - if let Some(p) = &path { - if let Some(target) = &p.0 { - if let Err(e) = solitaire_data::save_settings_to(target, &settings.0) { + if let Some(p) = &path + && let Some(target) = &p.0 + && let Err(e) = solitaire_data::save_settings_to(target, &settings.0) { warn!("failed to save settings after draw-mode toggle: {e}"); } - } - } changed.write(SettingsChangedEvent(settings.0.clone())); } } diff --git a/solitaire_engine/src/progress_plugin.rs b/solitaire_engine/src/progress_plugin.rs index 7f0c34f..f2e26f3 100644 --- a/solitaire_engine/src/progress_plugin.rs +++ b/solitaire_engine/src/progress_plugin.rs @@ -101,11 +101,10 @@ fn award_xp_on_win( total_xp: progress.0.total_xp, }); } - if let Some(target) = &path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if let Some(target) = &path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress: {e}"); } - } } } diff --git a/solitaire_engine/src/selection_plugin.rs b/solitaire_engine/src/selection_plugin.rs index 0f3d9a6..9060b1e 100644 --- a/solitaire_engine/src/selection_plugin.rs +++ b/solitaire_engine/src/selection_plugin.rs @@ -234,9 +234,9 @@ fn handle_selection_keys( // 2. Tableau stack move — count = full face-up run length from the source. let activate = keys.just_pressed(KeyCode::Enter) || keys.just_pressed(KeyCode::Space); - if activate { - if let Some(ref pile) = selection.selected_pile.clone() { - if let Some(card) = game + if activate + && let Some(ref pile) = selection.selected_pile.clone() + && let Some(card) = game .0 .piles .get(pile) @@ -266,8 +266,8 @@ fn handle_selection_keys( let start = p.cards.len().saturating_sub(run_len); p.cards.get(start) }); - if let Some(bottom) = bottom_card { - if let Some((dest, count)) = + if let Some(bottom) = bottom_card + && let Some((dest, count)) = best_tableau_destination_for_stack(bottom, pile, &game.0, run_len) { moves.write(MoveRequestEvent { @@ -278,7 +278,6 @@ fn handle_selection_keys( selection.selected_pile = None; return; } - } // --- Fallback: single-card move to any destination --- // Covers non-tableau sources (Waste, Foundation) that have no @@ -292,8 +291,6 @@ fn handle_selection_keys( selection.selected_pile = None; } } - } - } } // --------------------------------------------------------------------------- @@ -330,11 +327,10 @@ fn try_foundation_dest( use solitaire_core::rules::can_place_on_foundation; for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] { let dest = PileType::Foundation(suit); - if let Some(pile) = game.piles.get(&dest) { - if can_place_on_foundation(card, pile, suit) { + if let Some(pile) = game.piles.get(&dest) + && can_place_on_foundation(card, pile, suit) { return Some(dest); } - } } None } diff --git a/solitaire_engine/src/stats_plugin.rs b/solitaire_engine/src/stats_plugin.rs index 0febcf5..4ffdc33 100644 --- a/solitaire_engine/src/stats_plugin.rs +++ b/solitaire_engine/src/stats_plugin.rs @@ -326,8 +326,8 @@ fn spawn_stats_screen( } // Time Attack section - if let Some(ta) = time_attack { - if ta.active { + if let Some(ta) = time_attack + && ta.active { let mins = (ta.remaining_secs / 60.0).floor() as u64; let secs = (ta.remaining_secs % 60.0).floor() as u64; root.spawn(( @@ -336,7 +336,6 @@ fn spawn_stats_screen( TextColor(Color::srgb(1.0, 0.6, 0.2)), )); } - } // Dismiss hint root.spawn(( diff --git a/solitaire_engine/src/sync_plugin.rs b/solitaire_engine/src/sync_plugin.rs index dcdf889..ec462eb 100644 --- a/solitaire_engine/src/sync_plugin.rs +++ b/solitaire_engine/src/sync_plugin.rs @@ -176,21 +176,18 @@ fn poll_pull_result( let (merged, _conflicts) = merge(&local, &remote); // Persist merged state atomically. - if let Some(p) = &stats_path.0 { - if let Err(e) = save_stats_to(p, &merged.stats) { + if let Some(p) = &stats_path.0 + && let Err(e) = save_stats_to(p, &merged.stats) { warn!("sync: failed to persist stats: {e}"); } - } - if let Some(p) = &achievements_path.0 { - if let Err(e) = save_achievements_to(p, &merged.achievements) { + if let Some(p) = &achievements_path.0 + && let Err(e) = save_achievements_to(p, &merged.achievements) { warn!("sync: failed to persist achievements: {e}"); } - } - if let Some(p) = &progress_path.0 { - if let Err(e) = save_progress_to(p, &merged.progress) { + if let Some(p) = &progress_path.0 + && let Err(e) = save_progress_to(p, &merged.progress) { warn!("sync: failed to persist progress: {e}"); } - } // Update in-world resources. stats.0 = merged.stats; diff --git a/solitaire_engine/src/table_plugin.rs b/solitaire_engine/src/table_plugin.rs index 49ab16b..0a6a202 100644 --- a/solitaire_engine/src/table_plugin.rs +++ b/solitaire_engine/src/table_plugin.rs @@ -8,13 +8,14 @@ use bevy::prelude::*; use bevy::window::WindowResized; use solitaire_core::card::Suit; use solitaire_core::pile::PileType; -use solitaire_data::settings::Theme; use crate::events::HintVisualEvent; use crate::layout::{compute_layout, Layout, LayoutResource}; #[cfg(test)] use crate::layout::TABLE_COLOUR; use crate::settings_plugin::{SettingsChangedEvent, SettingsResource}; +#[cfg(test)] +use solitaire_data::Theme; /// Holds pre-loaded [`Handle`]s for the 5 selectable table backgrounds. /// diff --git a/solitaire_engine/src/weekly_goals_plugin.rs b/solitaire_engine/src/weekly_goals_plugin.rs index 483b9dd..1a0d6b4 100644 --- a/solitaire_engine/src/weekly_goals_plugin.rs +++ b/solitaire_engine/src/weekly_goals_plugin.rs @@ -49,13 +49,11 @@ fn roll_weekly_goals_on_startup( path: Res, ) { let week_key = current_iso_week_key(Local::now().date_naive()); - if progress.0.roll_weekly_goals_if_new_week(&week_key) { - if let Some(target) = &path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if progress.0.roll_weekly_goals_if_new_week(&week_key) + && let Some(target) = &path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress after weekly reset on startup: {e}"); } - } - } } fn evaluate_weekly_goals( @@ -114,13 +112,11 @@ fn evaluate_weekly_goals( } } - if any_change { - if let Some(target) = &path.0 { - if let Err(e) = save_progress_to(target, &progress.0) { + if any_change + && let Some(target) = &path.0 + && let Err(e) = save_progress_to(target, &progress.0) { warn!("failed to save progress after weekly goal update: {e}"); } - } - } } /// Resolve a goal id to its description (used for toasts).