From 4512c5ead9406206de32e37490b7a4ac792d93bf Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sun, 18 Dec 2022 13:40:53 -0500 Subject: Add bidding API --- server/src/main.rs | 70 +++++++++++++++++++++++++++++++++++++++++------------- server/src/play.rs | 2 +- 2 files changed, 55 insertions(+), 17 deletions(-) (limited to 'server/src') diff --git a/server/src/main.rs b/server/src/main.rs index 68baab7..a8429ec 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -9,8 +9,8 @@ use axum::{ routing::{delete, get, post}, Json, Router, }; +use protocol::bridge_engine::{Bid, GameStatePlayerView, Player}; use protocol::{Table, UserInfo}; -use protocol::bridge_engine::{GameStatePlayerView, Player}; use server::ContextExtension; use tower_cookies::{Cookie, CookieManagerLayer, Cookies}; use tower_http::trace::TraceLayer; @@ -18,37 +18,46 @@ use tracing::{info, log::warn}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod auth; mod error; -mod play; -mod server; #[cfg(debug_assertions)] mod fake_auth; +mod play; +mod server; use crate::{ auth::{OauthAuthenticator, SessionId}, - server::ServerContext, play::advance_play, + play::advance_play, + server::ServerContext, }; use crate::{ error::BridgeError, play::{DbJournal, Journal}, }; -use sqlx::{postgres::PgPoolOptions, PgPool}; use auth::Authenticator; +use sqlx::{postgres::PgPoolOptions, PgPool}; -async fn create_default_authenticator(db_pool: &PgPool) -> Box { +async fn create_default_authenticator( + db_pool: &PgPool, +) -> Box { Box::new(OauthAuthenticator::from_env(db_pool.clone()).await) } #[cfg(debug_assertions)] -async fn create_authenticator(db_pool: &PgPool) -> Box { +async fn create_authenticator( + db_pool: &PgPool, +) -> Box { const FAKE_AUTHENTICATOR: &str = "fake"; - if std::env::var("AUTHENTICATOR").unwrap_or("".to_string()) == FAKE_AUTHENTICATOR { - Box::new(fake_auth::FakeAuthenticator::new()) + if std::env::var("AUTHENTICATOR").unwrap_or("".to_string()) + == FAKE_AUTHENTICATOR + { + Box::new(fake_auth::FakeAuthenticator::new()) } else { create_default_authenticator(db_pool).await } } #[cfg(not(debug_assertions))] -async fn create_authenticator(db_pool: &PgPool) -> Box { +async fn create_authenticator( + db_pool: &PgPool, +) -> Box { create_default_authenticator(db_pool) } @@ -96,14 +105,14 @@ async fn main() { let app = Router::new(); #[cfg(debug_assertions)] - let app = app - .route("/api/fake_login", get(fake_login)); + let app = app.route("/api/fake_login", get(fake_login)); let app = app .route("/api/user/info", get(user_info)) .route("/api/table", post(create_table)) .route("/api/table", delete(leave_table)) .route("/api/table/:id", get(get_table_view)) + .route("/api/table/:id/bid", post(post_bid)) // .route("/api/user/table", get(user_table)) .route("/api/login", get(login)) .route(auth::LOGIN_CALLBACK, get(login_callback)) @@ -119,7 +128,8 @@ async fn main() { #[cfg(debug_assertions)] async fn fake_login() -> Html<&'static str> { - Html(r#" + Html( + r#" @@ -129,7 +139,8 @@ async fn fake_login() -> Html<&'static str> { - "#) + "#, + ) } async fn get_table_view( @@ -145,12 +156,39 @@ async fn get_table_view( while table.game().current_player() != Some(player_position) { advance_play(&mut table).await?; } - let response = - Json(GameStatePlayerView::from_game_state(table.game(), player_position)); + let response = Json(GameStatePlayerView::from_game_state( + table.game(), + player_position, + )); info!("Response: {response:#?}"); Ok(response) } +async fn post_bid( + _session: AuthenticatedSession, + extension: ContextExtension, + Path(id): Path, + Json(bid): Json, +) -> Result, BridgeError> { + info!("Getting table state for {id:}"); + let jnl = DbJournal::new(extension.db.clone(), id); + let mut table = play::Table::new_or_replay(jnl).await?; + if !table.game().is_bidding() { + return Err(BridgeError::InvalidRequest( + "Posting a bid requires that the game is in the bidding phase" + .to_string(), + )); + } + let player_position = Player::South; + if table.game().current_player() != Some(player_position) { + return Err(BridgeError::InvalidRequest(format!( + "It is not {player_position:?} to play" + ))); + } + table.bid(bid).await?; + Ok(Json(())) +} + async fn leave_table( session: AuthenticatedSession, extension: ContextExtension, diff --git a/server/src/play.rs b/server/src/play.rs index a6e78f2..e78a19e 100644 --- a/server/src/play.rs +++ b/server/src/play.rs @@ -115,7 +115,7 @@ impl Table { Ok(game) } - async fn bid(&mut self, bid: Bid) -> Result<(), BridgeError> { + pub async fn bid(&mut self, bid: Bid) -> Result<(), BridgeError> { let game = self.game.clone().bid(bid)?; self.journal.append(self.journal.next(), json!(game)).await?; self.game = game; -- cgit v1.2.3