chore: add pedantic workspace lints (#90)
Add [workspace.lints.rust] and wire each member crate up with [lints] workspace = true: unsafe_code = "deny" (forbid would break the Android JNI build) single_use_lifetimes = "warn" trivial_casts = "warn" unused_lifetimes = "warn" unused_qualifications = "warn" variant_size_differences = "warn" unexpected_cfgs = "warn" unsafe_code is "deny" rather than the issue's "forbid" so the three Android JNI FFI modules (android_keystore, android_clipboard, safe_area) can opt back in with a scoped #![allow(unsafe_code)] — forbid cannot be locally overridden. Pure crates carry no unsafe and stay clean. Clean up the warnings the new lints surface: - 150ish unused_qualifications removed via `cargo fix` (purely syntactic redundant-path-prefix removals). - table_plugin: the TABLE_COLOUR import was #[cfg(test)]-gated while the camera clear-colour used the fully-qualified path; unqualifying it left a non-test build with no import. Made the import unconditional instead. - assets/sources: the `as &[u8]` casts in embed_*_svg! coerce each fixed-size &[u8; N] to a uniform slice so the tuples fit the &[(&str, &[u8])] arrays — load-bearing, so scoped #[allow(trivial_casts)]. Workspace clippy -D warnings and the full test suite pass. Android build not compiled here (needs the NDK; built separately per CLAUDE.md §15) — the deny + scoped-allow keeps the JNI unsafe blocks legal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -203,7 +203,7 @@ impl Plugin for StatsPlugin {
|
||||
// `DefaultPlugins`; register it explicitly so the stats-scroll
|
||||
// system also runs cleanly under `MinimalPlugins` in tests.
|
||||
.add_message::<MouseWheel>()
|
||||
.add_message::<bevy::input::touch::TouchInput>()
|
||||
.add_message::<TouchInput>()
|
||||
// record_abandoned must read `move_count` BEFORE handle_new_game
|
||||
// clobbers it with a fresh game. These are NOT in StatsUpdate because
|
||||
// StatsUpdate (as a set) is ordered after GameMutation by external
|
||||
@@ -464,7 +464,7 @@ fn repaint_replay_selector_detail(
|
||||
/// Pure helper: render the detail line for the selected replay. Returns
|
||||
/// `"{duration} win on {date}"` plus a `" \u{2022} Shareable"` badge
|
||||
/// when a share URL is present. Empty when the history slice is empty.
|
||||
pub fn replay_selector_detail(replays: &[solitaire_data::Replay], index: usize) -> String {
|
||||
pub fn replay_selector_detail(replays: &[Replay], index: usize) -> String {
|
||||
let Some(r) = replays.get(index.min(replays.len().saturating_sub(1))) else {
|
||||
return String::new();
|
||||
};
|
||||
@@ -1325,7 +1325,7 @@ mod tests {
|
||||
fn draw_three_win_increments_draw_three_wins_only() {
|
||||
let mut app = headless_app();
|
||||
app.world_mut()
|
||||
.resource_mut::<crate::resources::GameStateResource>()
|
||||
.resource_mut::<GameStateResource>()
|
||||
.0
|
||||
.set_test_draw_mode(solitaire_core::DrawStockConfig::DrawThree);
|
||||
|
||||
@@ -1371,7 +1371,7 @@ mod tests {
|
||||
let mut app = headless_app();
|
||||
|
||||
app.world_mut()
|
||||
.resource_mut::<crate::resources::GameStateResource>()
|
||||
.resource_mut::<GameStateResource>()
|
||||
.0
|
||||
.set_test_move_count(3);
|
||||
|
||||
@@ -1501,7 +1501,7 @@ mod tests {
|
||||
fn zen_win_event_updates_zen_best_score_only() {
|
||||
let mut app = headless_app();
|
||||
app.world_mut()
|
||||
.resource_mut::<crate::resources::GameStateResource>()
|
||||
.resource_mut::<GameStateResource>()
|
||||
.0
|
||||
.mode = solitaire_core::game_state::GameMode::Zen;
|
||||
|
||||
@@ -1697,7 +1697,7 @@ mod tests {
|
||||
stats.0.win_streak_current = 3;
|
||||
}
|
||||
app.world_mut()
|
||||
.resource_mut::<crate::resources::GameStateResource>()
|
||||
.resource_mut::<GameStateResource>()
|
||||
.0
|
||||
.set_test_move_count(1);
|
||||
|
||||
@@ -1723,7 +1723,7 @@ mod tests {
|
||||
stats.0.win_streak_current = 1;
|
||||
}
|
||||
app.world_mut()
|
||||
.resource_mut::<crate::resources::GameStateResource>()
|
||||
.resource_mut::<GameStateResource>()
|
||||
.0
|
||||
.set_test_move_count(1);
|
||||
|
||||
@@ -1948,9 +1948,9 @@ mod tests {
|
||||
///
|
||||
/// Uses a fixed seed, DrawOne mode, Classic game, 2026-05-08 date.
|
||||
/// `time_seconds` and `share_url` are the only varying fields across tests.
|
||||
fn make_test_replay(time_seconds: u64, share_url: Option<String>) -> solitaire_data::Replay {
|
||||
fn make_test_replay(time_seconds: u64, share_url: Option<String>) -> Replay {
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2026, 5, 8).expect("valid date");
|
||||
let mut r = solitaire_data::Replay::new(
|
||||
let mut r = Replay::new(
|
||||
1,
|
||||
solitaire_core::DrawStockConfig::DrawOne,
|
||||
solitaire_core::game_state::GameMode::Classic,
|
||||
|
||||
Reference in New Issue
Block a user