Skip to main content

server/domain/phase/
core.rs

1use serde::{Deserialize, Serialize};
2use strum::AsRefStr;
3
4use crate::domain::{
5    Discarding, Finished, Playing, ScoringCrib, ScoringDealer, ScoringPone, Starting,
6    phase::wrap::{Wrap, WrapOrFinished},
7};
8
9/// Current phase of the Cribbage game.
10///
11/// The game progresses through a strict sequence of phases, each represented
12/// by a variant containing the phase-specific data.
13#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, AsRefStr)]
14pub enum Phase {
15    /// - `Starting` – Game is being created, players are joining and cutting for first dealer.
16    Starting(Starting),
17
18    /// - `Discarding` – Players discard two cards each to form the crib
19    Discarding(Discarding),
20
21    /// - `Playing` – Players alternately play cards; pegging occurs
22    Playing(Playing),
23
24    /// - `ScoringPone` – Pone’s hand is scored
25    ScoringPone(ScoringPone),
26
27    /// - `ScoringDealer` – Dealer’s hand is scored
28    ScoringDealer(ScoringDealer),
29
30    /// - `ScoringCrib` – Dealer’s crib is scored
31    ScoringCrib(ScoringCrib),
32
33    /// - `Finished` – Game over, final scores determined
34    Finished(Finished),
35}
36
37impl Phase {
38    pub(crate) fn or_finished(self) -> Phase {
39        match self {
40            Phase::Starting(s) => s.wrap(),
41            Phase::Discarding(s) => s.wrap(),
42            Phase::Playing(s) => s.wrap_or_finished(),
43            Phase::ScoringPone(s) => s.wrap_or_finished(),
44            Phase::ScoringDealer(s) => s.wrap_or_finished(),
45            Phase::ScoringCrib(s) => s.wrap_or_finished(),
46            Phase::Finished(s) => s.wrap(),
47        }
48    }
49}
50
51impl Default for Phase {
52    fn default() -> Self {
53        let starting = Starting::default();
54        starting.wrap()
55    }
56}
57
58impl std::fmt::Display for Phase {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        match self {
61            Self::Starting(state) => state.fmt(f),
62            Self::Discarding(state) => state.fmt(f),
63            Self::Playing(state) => state.fmt(f),
64            Self::ScoringPone(state) => state.fmt(f),
65            Self::ScoringDealer(state) => state.fmt(f),
66            Self::ScoringCrib(state) => state.fmt(f),
67            Self::Finished(state) => state.fmt(f),
68        }
69    }
70}