cards/src/api.rs
2024-05-03 19:13:00 -04:00

92 lines
2.7 KiB
Rust

use crate::AppState;
use crate::CAHd_game::*;
use axum::{
extract::{
ws::{Message, WebSocket, WebSocketUpgrade},
State,
},
response::IntoResponse,
};
use futures::{sink::SinkExt, stream::StreamExt};
use serde::Deserialize;
use std::sync::Arc;
/// New game request structure
#[derive(Debug, Deserialize)]
pub struct NewGameRequest {
/// Game name
pub name: String,
/// Game host
pub host: CAHPlayer,
/// Chosen packs
pub packs: Vec<u8>,
}
/// Game join request structure
pub struct GameJoinRequest {
/// Game id
pub id: u8, // increase later
/// Game password
pub password: String,
/// Player info
pub player: CAHPlayer,
}
pub async fn websocket_handler(
ws: WebSocketUpgrade,
State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
ws.on_upgrade(|socket| websocket(socket, state))
}
pub async fn websocket(stream: WebSocket, state: Arc<AppState>) {
// By splitting, we can send and receive at the same time.
let (mut sender, mut receiver) = stream.split();
let _greeting = sender
.send(Message::Text(format!(
"Greetings! \n\
{:#?} Card packs loaded\n\
{:#?} Current active games",
state.all_cards.lock().unwrap().len(),
state.games.lock().unwrap().len(),
)))
.await;
// Loop until a text message is found.
while let Some(Ok(message)) = receiver.next().await {
match message {
Message::Text(text) => {
tracing::debug!("Text: {}", text);
if let Ok(new_game) = serde_json::from_str::<NewGameRequest>(&text) {
tracing::debug!("{:#?}", &new_game);
state.games.lock().unwrap().push(CAHGame::new(new_game).expect("error creating game"));
} else {
// just echo
let _res = sender.send(Message::Text(text)).await;
}
}
Message::Binary(data) => {
tracing::debug!("Binary: {:?}", data)
}
Message::Close(c) => {
if let Some(cf) = c {
tracing::debug!(
"Close received with code: {} and reason: {}",
cf.code,
cf.reason
)
} else {
tracing::debug!("close received without close frame")
}
}
Message::Pong(ping) => {
tracing::debug!("Pong received with: {:?}", ping);
}
Message::Ping(pong) => {
tracing::debug!("Pong received with: {:?}", pong);
}
}
}
}