open_pql/base/isomorphic/
suit_mapping.rs1use super::Suit;
2
3#[derive(Clone, Debug, Default)]
5pub struct SuitMapping {
6 map: [Option<Suit>; 4],
7 next_suit: Suit,
8}
9
10impl SuitMapping {
11 pub const fn new() -> Self {
13 Self {
14 map: [None; 4],
15 next_suit: Suit::S,
16 }
17 }
18
19 pub const fn map_suit(&mut self, suit: Suit) -> Suit {
21 let idx = suit as usize;
22 if let Some(iso_suit) = self.map[idx] {
23 return iso_suit;
24 }
25
26 let iso_suit = self.next_suit;
27 self.map[idx] = Some(iso_suit);
28 self.next_suit = match self.next_suit {
29 Suit::S => Suit::H,
30 Suit::H => Suit::D,
31 Suit::D | Suit::C => Suit::C,
32 };
33
34 iso_suit
35 }
36
37 pub fn len(&self) -> usize {
39 self.map.iter().filter(|&&s| s.is_some()).count()
40 }
41
42 pub fn is_empty(&self) -> bool {
44 self.map.iter().all(|&s| s.is_none())
45 }
46
47 pub fn clear(&mut self) {
49 self.map = [None; 4];
50 self.next_suit = Suit::default();
51 }
52
53 #[cfg(test)]
54 pub const fn no_map() -> Self {
55 let mut mapping = Self::new();
56 mapping.map_suit(Suit::S);
57 mapping.map_suit(Suit::H);
58 mapping.map_suit(Suit::D);
59 mapping.map_suit(Suit::C);
60 mapping
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 const W: Suit = Suit::S;
69 const X: Suit = Suit::H;
70 const Y: Suit = Suit::D;
71 const Z: Suit = Suit::C;
72
73 #[test]
74 fn test_suit_mapping() {
75 let mut mapping = SuitMapping::new();
76
77 let s0 = mapping.map_suit(Suit::H);
78 assert_eq!(s0, W);
79
80 let s1 = mapping.map_suit(Suit::S);
81 assert_eq!(s1, X);
82
83 let s0_again = mapping.map_suit(Suit::H);
84 assert_eq!(s0_again, W);
85
86 let s2 = mapping.map_suit(Suit::C);
87 assert_eq!(s2, Y);
88
89 let s3 = mapping.map_suit(Suit::D);
90 assert_eq!(s3, Z);
91
92 assert_eq!(mapping.len(), 4);
93
94 mapping.clear();
95 assert_eq!(mapping.len(), 0);
96 assert!(mapping.is_empty());
97 }
98}