openpql_prelude/card/
suit_mapping.rs1use super::Suit;
2
3#[derive(Clone, Debug, Default)]
7pub struct SuitMapping {
8 map: [Option<Suit>; Suit::N_SUITS as usize],
9 next_suit: Suit,
10}
11
12impl SuitMapping {
13 pub const fn new() -> Self {
15 Self {
16 map: [None; Suit::N_SUITS as usize],
17 next_suit: Suit::S,
18 }
19 }
20
21 pub const fn map_suit(&mut self, suit: Suit) -> Suit {
23 let idx = suit as usize;
24 if let Some(iso_suit) = self.map[idx] {
25 return iso_suit;
26 }
27
28 let iso_suit = self.next_suit;
29 self.map[idx] = Some(iso_suit);
30 self.advance_suit();
31
32 iso_suit
33 }
34
35 pub fn len(&self) -> usize {
37 self.map.iter().filter(|&&s| s.is_some()).count()
38 }
39
40 pub fn is_empty(&self) -> bool {
42 self.map.iter().all(|&s| s.is_none())
43 }
44
45 const fn advance_suit(&mut self) {
46 self.next_suit = match self.next_suit {
47 Suit::S => Suit::H,
48 Suit::H => Suit::D,
49 _ => Suit::C,
50 };
51 }
52}
53
54#[cfg(test)]
55#[cfg_attr(coverage_nightly, coverage(off))]
56mod tests {
57 use super::*;
58
59 const W: Suit = Suit::S;
60 const X: Suit = Suit::H;
61 const Y: Suit = Suit::D;
62 const Z: Suit = Suit::C;
63
64 #[test]
65 fn test_suit_mapping() {
66 let mut mapping = SuitMapping::new();
67
68 assert_eq!(mapping.len(), 0);
69 assert!(mapping.is_empty());
70
71 let suits = [Suit::H, Suit::S, Suit::H, Suit::C, Suit::D];
72 let mapped = suits.map(|suit| mapping.map_suit(suit));
73
74 assert_eq!(mapped, [W, X, W, Y, Z]);
75
76 assert_eq!(mapping.len(), 4);
77 }
78}