Skip to main content

server/services/action/
start_game.rs

1use crate::{
2    domain::{GameCommand, GameId, UserId},
3    error::{ServerError, bug},
4    server_state::ServerState,
5    services::queries::get_game,
6};
7
8/// Acknowledges the cuts for deal, then starts a hosted game for the specified user.
9///
10/// # Parameters
11///
12/// - `server_state`: The shared server state containing the game and database.
13/// - `user_id`: The ID of the user starting the game.
14/// - `game_id`: The ID of the game to start.
15///
16/// # Returns
17///
18/// Returns `Ok(())` if the game was successfully started.
19/// Returns a `ServerError` if the action is forbidden, the game is not found,
20/// or another internal error occurs.
21pub async fn start_game(
22    server_state: ServerState,
23    user_id: UserId,
24    game_id: GameId,
25) -> Result<(), ServerError> {
26    let game = get_game(server_state.clone(), game_id).await?;
27
28    if let Some(game) = game {
29        let player = game
30            .validate_user(user_id)
31            .ok_or(ServerError::Forbidden("start game".into()))?;
32
33        let aggregate_id = game_id.value().to_string();
34
35        let command = GameCommand::StartGame { player };
36
37        server_state
38            .cqrs
39            .execute(&aggregate_id, command)
40            .await
41            .map_err(bug!())?;
42
43        Ok(())
44    } else {
45        Err(ServerError::NotFound)
46    }
47}