refactor: type game availability state
Game::availability used string labels that were carried through persisted library data, protocol summaries, and the Tauri-facing game payload. That allowed invalid states to exist and required legacy summary conversion code to defensively map strings back into protocol availability values. Move Availability to lanspread-db and re-export it from lanspread-proto so the persisted Game type and wire GameSummary type share one serde enum. The JSON spelling stays Ready, Downloading, or LocalOnly, so the serialized shape does not change for current library indexes or peer payloads. Add typed helpers for sentinel-derived download state. Game::set_downloaded keeps downloaded and Ready/LocalOnly in lockstep and intentionally collapses non-ready local state, including Downloading, back to LocalOnly. That matches the current local-summary contract where active operations are suppressed instead of advertised as Downloading. Game::normalized_availability keeps the legacy Game-to-summary path from publishing an inconsistent Ready value when downloaded is false. Update the follow-up status note so typed availability is no longer listed as open work. Test Plan: - just fmt - just test - just clippy - just build Refs: none
This commit is contained in:
@@ -7,10 +7,12 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use lanspread_db::db::{AVAILABILITY_READY, Game, GameFileDescription};
|
||||
use lanspread_proto::{Availability, GameSummary, LibraryDelta, LibrarySnapshot};
|
||||
#[cfg(test)]
|
||||
use lanspread_db::db::Availability;
|
||||
use lanspread_db::db::{Game, GameFileDescription};
|
||||
use lanspread_proto::{GameSummary, LibraryDelta, LibrarySnapshot};
|
||||
|
||||
use crate::{library::compute_library_digest, local_games::availability_label};
|
||||
use crate::library::compute_library_digest;
|
||||
pub type PeerId = String;
|
||||
|
||||
/// Information about a discovered peer.
|
||||
@@ -292,11 +294,9 @@ impl PeerGameDB {
|
||||
existing.size = game.size;
|
||||
}
|
||||
if game_is_ready(game) {
|
||||
existing.downloaded = true;
|
||||
existing.availability = AVAILABILITY_READY.to_string();
|
||||
existing.set_downloaded(true);
|
||||
} else if !existing.downloaded {
|
||||
existing.availability =
|
||||
availability_label(&game.availability).to_string();
|
||||
existing.availability = game.availability.clone();
|
||||
}
|
||||
if game.installed {
|
||||
existing.installed = true;
|
||||
@@ -305,7 +305,6 @@ impl PeerGameDB {
|
||||
.or_insert_with(|| {
|
||||
let mut game_clone = summary_to_game(game);
|
||||
game_clone.peer_count = *peer_counts.get(&game.id).unwrap_or(&0);
|
||||
game_clone.downloaded = game_is_ready(game);
|
||||
game_clone
|
||||
});
|
||||
}
|
||||
@@ -728,7 +727,7 @@ fn create_peer_whitelist(peer_scores: HashMap<SocketAddr, usize>) -> Vec<SocketA
|
||||
}
|
||||
|
||||
fn game_is_ready(summary: &GameSummary) -> bool {
|
||||
summary.availability == Availability::Ready
|
||||
summary.availability.is_downloaded()
|
||||
}
|
||||
|
||||
fn summary_to_game(summary: &GameSummary) -> Game {
|
||||
@@ -746,9 +745,9 @@ fn summary_to_game(summary: &GameSummary) -> Game {
|
||||
version: "1.0".to_string(),
|
||||
genre: String::new(),
|
||||
size: summary.size,
|
||||
downloaded: summary.downloaded,
|
||||
downloaded: summary.availability.is_downloaded(),
|
||||
installed: summary.installed,
|
||||
availability: availability_label(&summary.availability).to_string(),
|
||||
availability: summary.availability.clone(),
|
||||
eti_game_version,
|
||||
local_version: None,
|
||||
peer_count: 0,
|
||||
@@ -759,8 +758,6 @@ fn summary_to_game(summary: &GameSummary) -> Game {
|
||||
mod tests {
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use lanspread_db::db::AVAILABILITY_LOCAL_ONLY;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn addr(port: u16) -> SocketAddr {
|
||||
@@ -824,7 +821,7 @@ mod tests {
|
||||
assert_eq!(games.len(), 1);
|
||||
assert_eq!(games[0].peer_count, 0);
|
||||
assert!(!games[0].downloaded);
|
||||
assert_eq!(games[0].availability, AVAILABILITY_LOCAL_ONLY);
|
||||
assert_eq!(games[0].availability, Availability::LocalOnly);
|
||||
assert_eq!(games[0].eti_game_version, None);
|
||||
|
||||
assert!(db.peers_with_game("game").is_empty());
|
||||
|
||||
Reference in New Issue
Block a user