Skip to main content

server/services/queries/
get_available_games.rs

1use chrono::{DateTime, Utc};
2
3use crate::{
4    convertors::available_game_row_to_available_game,
5    database::select_available_games,
6    domain::{AvailableGame, UserId},
7    error::{ServerError, bug},
8    server_state::ServerState,
9};
10
11/// Retrieves a list of available games that the specified user can play or join.
12///
13/// This function fetches games from the server that the specified user
14/// is eligible to join. Results can be filtered by a search string and
15/// paginated using the `last_created_at` parameter.
16///
17/// # Parameters
18///
19/// - `server_state`: The shared server state containing the games database.
20/// - `user_id`: The ID of the user requesting the available games.
21/// - `filter`: A string used to filter games by name or other criteria.
22/// - `last_created_at`: Optional timestamp for pagination; only games created
23///   after this timestamp are returned.
24///
25/// # Returns
26///
27/// Returns a tuple `(games, has_more, last_created_at)`:
28/// - `games`: A `Vec<AvailableGame>` containing the available games matching
29///   the filter and pagination criteria.
30/// - `has_more`: `true` if there are more games to fetch beyond this page.
31/// - `last_created_at`: The timestamp of the last game returned, to be used
32///   for the next paginated request.
33///
34/// Returns a `ServerError` if there is a problem accessing the database or
35/// processing the request.
36pub async fn get_available_games(
37    server_state: ServerState,
38    user_id: UserId,
39    filter: String,
40    last_created_at: Option<DateTime<Utc>>,
41) -> Result<(Vec<AvailableGame>, bool, Option<DateTime<Utc>>), ServerError> {
42    let pool = server_state.pool.clone();
43    const CHUNK_SIZE: u32 = 5;
44
45    let filter = (!filter.is_empty()).then_some(filter);
46
47    let chunk =
48        select_available_games(&*pool, CHUNK_SIZE, last_created_at, filter, user_id.value())
49            .await
50            .map_err(bug!())?;
51
52    let games = chunk
53        .games
54        .into_iter()
55        .map(|row| {
56            let game = available_game_row_to_available_game(row).map_err(bug!())?;
57            Ok::<_, ServerError>(game)
58        })
59        .collect::<Result<Vec<_>, _>>()?;
60
61    Ok((games, chunk.has_more, chunk.last_created_at))
62}