Skip to main content

server/services/action/
cut_for_deal.rs

1use crate::{
2    domain::{GameCommand, GameId, UserId},
3    error::{ServerError, bug},
4    server_state::ServerState,
5    services::queries::get_game,
6};
7
8/// Performs the "cut for deal" action for a user in a specific game.
9///
10/// This function represents the step where a user cuts the deck to determine
11/// the dealer for the game. It updates the server state accordingly.
12///
13/// # Parameters
14///
15/// - `server_state`: The shared server state containing the game and database.
16/// - `user_id`: The ID of the user performing the cut.
17/// - `game_id`: The ID of the game in which the cut is performed.
18///
19/// # Returns
20///
21/// Returns `Ok(())` on success. Returns a `ServerError` if the action is forbidden,
22/// the game is not found, or another internal error occurs.
23pub async fn cut_for_deal(
24    server_state: ServerState,
25    user_id: UserId,
26    game_id: GameId,
27) -> Result<(), ServerError> {
28    let game = get_game(server_state.clone(), game_id).await?;
29
30    if let Some(game) = game {
31        let player = game
32            .validate_user(user_id)
33            .ok_or(ServerError::Forbidden("cut for deal".into()))?;
34
35        let aggregate_id = game_id.value().to_string();
36
37        let command = GameCommand::CutForDeal { player };
38
39        server_state
40            .cqrs
41            .execute(&aggregate_id, command)
42            .await
43            .map_err(bug!())?;
44
45        Ok(())
46    } else {
47        Err(ServerError::NotFound)
48    }
49}