Skip to main content

server/domain/
events.rs

1use cqrs_es::DomainEvent;
2use serde::{Deserialize, Serialize};
3use strum::AsRefStr;
4
5#[cfg(test)]
6use crate::domain::Game;
7use crate::domain::{Card, Dealer, GameId, Hand, Pegging, Player, StarterCut, UserId};
8
9/// Domain events which represent the **single source of truth** for game history and
10/// are persisted in the event store. The current game state is derived by folding them
11/// in order.
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, AsRefStr)]
13pub enum GameEvent {
14    /// A user created a lobby game and is waiting for another user to join
15    LobbyGameCreated {
16        /// The identity of the game that was created.
17        game_id: GameId,
18
19        /// The user that created the game.
20        host: UserId,
21
22        /// The name assigned to the game. It's possible this may be
23        /// the same as another game; the `game_id` provides the unique id.
24        name: String,
25    },
26
27    /// A user joined a game that was previously a lobby game.
28    LobbyGameJoined {
29        /// The user that joined the game.
30        guest: UserId,
31    },
32
33    /// A user a computer game.
34    ComputerGameCreated {
35        /// The identity of the game that was created.
36        game_id: GameId,
37
38        /// The user that created the game.
39        host: UserId,
40
41        /// The computer "user" that will play against the host.
42        guest: UserId,
43
44        /// The name assigned to the game. It's possible this may be
45        /// the same as another game; the `game_id` provides the unique id.
46        name: String,
47    },
48
49    /// A player cut a card for the choice of initial dealer.
50    CutForDealMade {
51        /// The player identity (essentially host or guest)
52        player: Player,
53
54        /// The card that was cut.
55        cut: Card,
56    },
57
58    /// A player has acknowledged the cut for deal. When both players
59    /// have acknowledge the cards will be dealt and discarding begin.
60    GameStarted {
61        /// The player identity (essentially host or guest)
62        player: Player,
63    },
64
65    /// Both plays have cut for deal (and acknowledged the cut); the
66    /// cuts were the same rank, so the cut needs to be redrawn.
67    CutForDealTied,
68
69    /// Both plays have cut for deal (and acknowledged the cut); the
70    /// cuts were different, so the dealer is selected and the deal
71    /// can progress.
72    CutForDealDecided {
73        /// The selected dealer.
74        dealer: Dealer,
75    },
76
77    /// A hand has been dealt to the player, following `CutForDealDecided`
78    /// or `NextRoundStarted`.
79    HandDealt {
80        /// The player identity (essentially host or guest)
81        player: Player,
82
83        /// The hand that has been dealt.
84        hand: Hand,
85    },
86
87    /// A player has discarded cards to the crib.
88    CardsDiscarded {
89        /// The player identity (essentially host or guest)
90        player: Player,
91
92        /// The cards that were discarded.
93        cards: Vec<Card>,
94    },
95
96    /// Both players have discarded cards to the crib and the "Starter"
97    /// card selected.
98    StarterSelected {
99        /// The starter card.
100        cut: StarterCut,
101
102        /// Record `HisHeels`.
103        pegging: Pegging,
104    },
105
106    /// A player has played a card during the `Playing` (or Pegging) phase.
107    CardPlayed {
108        /// The player identity (essentially host or guest)
109        player: Player,
110
111        /// The card that was played.
112        card: Card,
113
114        /// Points awarded during pegging (may include 31 for 2).
115        pegging: Pegging,
116    },
117
118    /// A player has called `Go` during the `Playing` (or Pegging) phase.
119    GoCalled {
120        /// The player identity (essentially host or guest)
121        player: Player,
122
123        /// Points awarded for the `Go`.
124        pegging: Pegging,
125    },
126
127    /// A player has `acknowledged` `End of Plays`; when both players
128    /// have acknowledged then the Pone's hand will be scored.
129    PoneScored {
130        /// The player identity (essentially host or guest)
131        player: Player,
132
133        /// The pone's hand scores.
134        pegging: Pegging,
135    },
136
137    /// A player has `acknowledged` the `Pone Score`; when both players
138    /// have acknowledged then the Dealer's hand will be scored.
139    DealerScored {
140        /// The player identity (essentially host or guest)
141        player: Player,
142
143        /// The dealer's hand scores.
144        pegging: Pegging,
145    },
146
147    /// A player has `acknowledged` the `Dealer Score`; when both players
148    /// have acknowledged then the Dealer's crib will be scored.
149    CribScored {
150        /// The player identity (essentially host or guest)
151        player: Player,
152
153        /// The dealer's crib scores.
154        pegging: Pegging,
155    },
156
157    /// A player has `acknowledged` the `Crib Score`; when both players
158    /// have acknowledged then the next round will start, swapping dealers.
159    NextRoundStarted {
160        /// The player identity (essentially host or guest)
161        player: Player,
162    },
163
164    #[cfg(test)]
165    /// A preset game state has been loaded, to enable easy test setup.
166    /// This event is emitted during testing only; it may not represent
167    /// a 'real' state, but rather a suitable state to enable the test.
168    /// This is boxed to avoid large variant size difference clippy warnings.
169    GamePreloaded {
170        /// The full preloaded game object.
171        game: Box<Game>,
172    },
173}
174
175impl DomainEvent for GameEvent {
176    fn event_type(&self) -> String {
177        String::from(self.as_ref())
178    }
179
180    fn event_version(&self) -> String {
181        String::from(env!("CARGO_PKG_VERSION"))
182    }
183}