server/domain/types/
pending.rs1use std::collections::HashSet;
2
3use itertools::Itertools;
4use serde::{Deserialize, Serialize};
5
6use crate::domain::{PLAYER0, PLAYER1, Player};
7
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(transparent)]
21pub struct Pending(HashSet<Player>);
22
23pub trait HasPending {
25 fn pending(&self) -> &Pending;
27
28 fn pending_mut(&mut self) -> &mut Pending;
30}
31
32impl Pending {
33 #[must_use]
35 #[inline]
36 pub fn finished(&self) -> bool {
37 self.0.is_empty()
38 }
39
40 #[must_use]
42 #[inline]
43 pub fn waiting_on(&self, player: Player) -> bool {
44 self.0.contains(&player)
45 }
46
47 #[must_use]
51 pub fn acknowledge(&mut self, player: Player) -> bool {
52 self.0.remove(&player);
53 self.0.is_empty()
54 }
55}
56
57impl Default for Pending {
58 fn default() -> Self {
59 Self(HashSet::from([PLAYER0, PLAYER1]))
60 }
61}
62
63#[cfg(test)]
64impl From<&[Player]> for Pending {
65 fn from(value: &[Player]) -> Self {
66 Self(HashSet::from_iter(value.to_owned()))
67 }
68}
69
70impl std::fmt::Display for Pending {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 let pending = self.0.iter().map(|p| p.to_string()).join(", ");
73 write!(f, "Pending({pending})")
74 }
75}