ckc_rs/cards/
three.rs

1use crate::cards::HandValidator;
2use crate::{CKCNumber, HandError, PokerCard, Shifty};
3use core::slice::Iter;
4
5#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
6pub struct Three(pub [CKCNumber; 3]);
7
8impl Three {
9    //region getters
10
11    #[must_use]
12    pub fn second(&self) -> CKCNumber {
13        self.0[1]
14    }
15
16    #[must_use]
17    pub fn third(&self) -> CKCNumber {
18        self.0[2]
19    }
20
21    pub fn set_first(&mut self, card_number: CKCNumber) {
22        self.0[0] = card_number;
23    }
24
25    pub fn set_second(&mut self, card_number: CKCNumber) {
26        self.0[1] = card_number;
27    }
28
29    pub fn set_third(&mut self, card_number: CKCNumber) {
30        self.0[2] = card_number;
31    }
32
33    //endregion
34
35    #[must_use]
36    pub fn to_arr(&self) -> [CKCNumber; 3] {
37        self.0
38    }
39
40    fn from_index(index: &str) -> Option<[CKCNumber; 3]> {
41        let mut esses = index.split_whitespace();
42
43        let first = CKCNumber::from_index(esses.next()?);
44        let second = CKCNumber::from_index(esses.next()?);
45        let third = CKCNumber::from_index(esses.next()?);
46        let hand: [CKCNumber; 3] = [first, second, third];
47        Some(hand)
48    }
49}
50
51impl From<[CKCNumber; 3]> for Three {
52    fn from(array: [CKCNumber; 3]) -> Self {
53        Three(array)
54    }
55}
56
57impl TryFrom<&'static str> for Three {
58    type Error = HandError;
59
60    fn try_from(index: &'static str) -> Result<Self, Self::Error> {
61        match Three::from_index(index) {
62            None => Err(HandError::InvalidIndex),
63            Some(three) => Ok(Three::from(three)),
64        }
65    }
66}
67
68impl HandValidator for Three {
69    fn are_unique(&self) -> bool {
70        (self.first() != self.second()) && (self.first() != self.third()) && (self.second() != self.third())
71    }
72
73    fn first(&self) -> CKCNumber {
74        self.0[0]
75    }
76
77    fn sort(&self) -> Three {
78        let mut array = *self;
79        array.sort_in_place();
80        array
81    }
82
83    fn sort_in_place(&mut self) {
84        self.0.sort_unstable();
85        self.0.reverse();
86    }
87
88    fn iter(&self) -> Iter<'_, CKCNumber> {
89        self.0.iter()
90    }
91}
92
93impl Shifty for Three {
94    fn shift_suit(&self) -> Self {
95        Three([
96            self.first().shift_suit(),
97            self.second().shift_suit(),
98            self.third().shift_suit(),
99        ])
100    }
101}
102
103#[cfg(test)]
104#[allow(non_snake_case)]
105mod cards_three_tests {
106    use super::*;
107    use crate::CardNumber;
108
109    #[test]
110    fn sort() {
111        let three = Three::try_from("KC QD A♠").unwrap().sort();
112
113        let expected = Three::try_from("A♠ KC QD").unwrap();
114
115        assert_eq!(three, expected);
116    }
117
118    #[test]
119    fn default() {
120        let three = Three::default();
121
122        assert_eq!(three.first(), CardNumber::BLANK);
123        assert_eq!(three.second(), CardNumber::BLANK);
124        assert_eq!(three.third(), CardNumber::BLANK);
125        assert!(three.contain_blank());
126        assert!(!three.are_unique());
127        assert!(!three.is_valid());
128    }
129
130    #[test]
131    fn try_from__index() {
132        let three = Three::try_from("A♠ K♠ Q♠");
133
134        assert!(three.is_ok());
135        let three = three.unwrap();
136        assert_eq!(three.first(), CardNumber::ACE_SPADES);
137        assert_eq!(three.second(), CardNumber::KING_SPADES);
138        assert_eq!(three.third(), CardNumber::QUEEN_SPADES);
139        assert!(!three.contain_blank());
140        assert!(three.are_unique());
141        assert!(three.is_valid());
142    }
143
144    #[test]
145    fn try_from__index__blank() {
146        let three = Three::try_from("A♠ K♠ XX");
147
148        assert!(three.is_ok());
149        let three = three.unwrap();
150        assert_eq!(three.first(), CardNumber::ACE_SPADES);
151        assert_eq!(three.second(), CardNumber::KING_SPADES);
152        assert_eq!(three.third(), CardNumber::BLANK);
153        assert!(three.contain_blank());
154        assert!(!three.is_valid());
155    }
156
157    #[test]
158    fn try_from__index__too_short() {
159        let three = Three::try_from("A♠ K♠");
160
161        assert!(three.is_err());
162    }
163
164    #[test]
165    fn shifty__shift_suit() {
166        assert_eq!(
167            Three::try_from("A♠ K♠ Q♠").unwrap().shift_suit(),
168            Three::try_from("AH KH QH").unwrap()
169        )
170    }
171}