use serde::{Deserialize, Serialize}; use crate::error::RpcResult; use crate::wire::WireMessage; #[derive( Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, )] pub struct AccountRef { pub high: i32, pub low: i32, } impl AccountRef { pub const fn new(high: i32, low: i32) -> Self { Self { high, low } } pub const fn is_zero(self) -> bool { self.high == 0 && self.low == 0 } } impl std::fmt::Display for AccountRef { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}-{}", self.high, self.low) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum HomeRequestKind { Login, GoHome, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "op", rename_all = "snake_case")] pub enum GameRequest { LoadHome { account: AccountRef, kind: HomeRequestKind, }, ClientCapabilities { account: AccountRef, ping_ms: i32, }, EndClientTurn { account: AccountRef, #[serde(with = "crate::base64::serde_bytes")] payload: Vec, }, Disconnect { account: AccountRef, }, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "result", rename_all = "snake_case")] pub enum GameResponse { Messages { messages: Vec }, Empty, } impl GameResponse { pub fn messages(messages: Vec) -> Self { Self::Messages { messages } } pub fn into_messages(self) -> Vec { match self { GameResponse::Messages { messages } => messages, GameResponse::Empty => Vec::new(), } } } #[async_trait::async_trait] pub trait GameApi: Send + Sync + 'static { async fn load_home( &self, account: AccountRef, kind: HomeRequestKind, ) -> RpcResult>; async fn client_capabilities(&self, account: AccountRef, ping_ms: i32) -> RpcResult<()>; async fn end_client_turn( &self, account: AccountRef, payload: Vec, ) -> RpcResult>; async fn disconnect(&self, account: AccountRef) -> RpcResult<()>; }