server/services/action/score_crib.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 current dealer score and goes on to score the crib for the specified user
9/// if both players have acknowledged.
10///
11/// # Parameters
12///
13/// - `server_state`: The shared server state containing the game and database.
14/// - `user_id`: The ID of the user scoring the crib.
15/// - `game_id`: The ID of the game containing the crib.
16///
17/// # Returns
18///
19/// Returns `Ok(())` if the crib was successfully scored.
20/// Returns a `ServerError` if the action is forbidden, the game is not found,
21/// the crib cannot be scored yet, or another internal error occurs.
22pub async fn score_crib(
23 server_state: ServerState,
24 user_id: UserId,
25 game_id: GameId,
26) -> Result<(), ServerError> {
27 let game = get_game(server_state.clone(), game_id).await?;
28
29 if let Some(game) = game {
30 let player = game
31 .validate_user(user_id)
32 .ok_or(ServerError::Forbidden("score crib".into()))?;
33
34 let aggregate_id = game_id.value().to_string();
35
36 let command = GameCommand::ScoreCrib { player };
37
38 server_state
39 .cqrs
40 .execute(&aggregate_id, command)
41 .await
42 .map_err(bug!())?;
43
44 Ok(())
45 } else {
46 Err(ServerError::NotFound)
47 }
48}