Format ApiMessage

This commit is contained in:
Aode (lion) 2022-01-02 11:19:45 -06:00
parent cbdc46aca6
commit 3e4221ce8a
2 changed files with 48 additions and 8 deletions

View file

@ -34,6 +34,19 @@ pub(crate) struct Move {
pub(crate) piece: Piece,
pub(crate) from: Coordinates,
pub(crate) to: Coordinates,
}
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct Promote {
pub(crate) location: Coordinates,
pub(crate) kind: PieceKind,
}
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ApiMessage<T> {
pub(crate) data: T,
pub(crate) game_id: GameId,
}

View file

@ -16,20 +16,25 @@ mod api_types;
mod board_state;
mod init_tracing;
use api_types::{GameId, GameStart, Move, Start};
use api_types::{ApiMessage, GameId, GameStart, Move, Promote, Start};
struct Reply {
board_state: board_state::GameState,
}
struct MoveSession {
action: Move,
enum Action {
Move(Move),
Promote(Promote),
}
struct Session {
action: Action,
reply: tokio::sync::oneshot::Sender<Reply>,
}
#[derive(Clone, Debug)]
struct GameData {
sender: Sender<MoveSession>,
sender: Sender<Session>,
}
#[derive(Clone, Default)]
@ -78,7 +83,10 @@ async fn start(Json(start): Json<Start>, game_state: Data<GameState>) -> HttpRes
while let Ok(Some(msg)) =
actix_web::rt::time::timeout(Duration::from_secs(60 * 5), rx.recv()).await
{
board_state.handle(msg.action);
match msg.action {
Action::Move(action) => board_state.handle(action),
Action::Promote(_) => unimplemented!(),
}
let _ = msg.reply.send(Reply {
board_state: board_state.clone(),
@ -96,11 +104,29 @@ async fn start(Json(start): Json<Start>, game_state: Data<GameState>) -> HttpRes
})
}
async fn make_move(Json(action): Json<Move>, game_state: Data<GameState>) -> HttpResponse {
if let Some(data) = game_state.data_for_id(&action.game_id) {
async fn make_move(
Json(action): Json<ApiMessage<Move>>,
game_state: Data<GameState>,
) -> HttpResponse {
send_message(action.game_id, Action::Move(action.data), game_state).await
}
async fn promote_pawn(
Json(action): Json<ApiMessage<Promote>>,
game_state: Data<GameState>,
) -> HttpResponse {
send_message(action.game_id, Action::Promote(action.data), game_state).await
}
async fn send_message(
game_id: GameId,
action: Action,
game_state: Data<GameState>,
) -> HttpResponse {
if let Some(data) = game_state.data_for_id(&game_id) {
let (reply, rx) = tokio::sync::oneshot::channel();
let res = data.sender.send(MoveSession { action, reply }).await;
let res = data.sender.send(Session { action, reply }).await;
if res.is_err() {
return HttpResponse::InternalServerError().finish();
@ -134,6 +160,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
)
.route("/start", actix_web::web::post().to(start))
.route("/move", actix_web::web::post().to(make_move))
.route("/promote", actix_web::web::post().to(promote_pawn))
})
.bind("0.0.0.0:8000")?
.run()