use crate::{
cards::deck::DeckConfig,
game::{
rules::GameRules,
score::{RoundScore, VariantPlayerScore},
state::{GamePhase, GameState},
variants::basic::{game::BasicRummyGame, rules::BasicRules, score::BasicScore},
},
serialization::{cards::SerializableDeck, player::SerializablePlayer},
};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, sync::Arc};
#[derive(Serialize, Deserialize)]
pub(super) struct SerializableBasicRummyGame {
state: SerializableGameState<BasicScore, BasicRules>,
rules: BasicRules,
}
impl SerializableBasicRummyGame {
pub fn from_game(game: &BasicRummyGame) -> Self {
Self {
state: SerializableGameState::from_gamestate(&game.state),
rules: game.rules.clone(),
}
}
pub fn into_game(self) -> BasicRummyGame {
BasicRummyGame {
state: self.state.into_gamestate(),
rules: self.rules,
}
}
}
impl Serialize for BasicRummyGame {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let serializable_game = SerializableBasicRummyGame::from_game(self);
serializable_game.serialize(serializer)
}
}
impl<'de> serde::Deserialize<'de> for BasicRummyGame {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let serialized_game = SerializableBasicRummyGame::deserialize(deserializer)?;
let game = serialized_game.into_game();
Ok(game)
}
}
#[derive(Serialize, Deserialize)]
pub(super) struct SerializableGameState<P: VariantPlayerScore, R: GameRules<VariantScore = P>> {
pub phase: GamePhase,
pub players: Vec<SerializablePlayer>,
pub deck: SerializableDeck,
pub deck_config: DeckConfig,
pub current_player: usize,
pub current_round: usize,
pub round_scores: HashMap<usize, RoundScore<P>>,
pub variant_state: R::VariantState,
}
impl<P: VariantPlayerScore, R: GameRules<VariantScore = P>> SerializableGameState<P, R> {
pub fn into_gamestate(self) -> GameState<P, R> {
let deck_config = Arc::new(self.deck_config);
let players = self
.players
.into_iter()
.map(|p| p.into_player(deck_config.clone()))
.collect();
let deck = self.deck.into_deck(deck_config);
GameState {
phase: self.phase,
players,
deck,
current_player: self.current_player,
current_round: self.current_round,
round_scores: self.round_scores,
variant_state: self.variant_state,
}
}
pub fn from_gamestate(state: &GameState<P, R>) -> Self {
let players = state
.players
.iter()
.map(SerializablePlayer::from_player)
.collect();
let deck = SerializableDeck::from_deck(&state.deck);
Self {
phase: state.phase,
players,
deck,
deck_config: (*state.deck.config).clone(),
current_player: state.current_player,
current_round: state.current_round,
round_scores: state.round_scores.clone(),
variant_state: state.variant_state.clone(),
}
}
}