Format ApiMessage
This commit is contained in:
parent
cbdc46aca6
commit
3e4221ce8a
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue