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}