open_pql/base/
rank.rs

1use super::*;
2
3/// Enum for Ranks
4#[derive(
5    Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd, Hash, Display, Default,
6)]
7pub enum Rank {
8    /// Duece
9    #[default]
10    #[display("2")]
11    R2 = 0,
12    /// Three
13    #[display("3")]
14    R3,
15    /// Four
16    #[display("4")]
17    R4,
18    /// Five
19    #[display("5")]
20    R5,
21    /// Six
22    #[display("6")]
23    R6,
24    /// Seven
25    #[display("7")]
26    R7,
27    /// Eight
28    #[display("8")]
29    R8,
30    /// Nine
31    #[display("9")]
32    R9,
33    /// Ten
34    #[display("T")]
35    RT,
36    /// Jack
37    #[display("J")]
38    RJ,
39    /// Queen
40    #[display("Q")]
41    RQ,
42    /// King
43    #[display("K")]
44    RK,
45    /// Ace
46    #[display("A")]
47    RA,
48}
49
50impl Rank {
51    /// [ R2, R3, R4, R5, R6, R7, R8, R9, RT, RJ, RQ, RK, RA ]
52    pub const ARR_ALL: [Self; N_RANKS as usize] = [
53        Self::R2,
54        Self::R3,
55        Self::R4,
56        Self::R5,
57        Self::R6,
58        Self::R7,
59        Self::R8,
60        Self::R9,
61        Self::RT,
62        Self::RJ,
63        Self::RQ,
64        Self::RK,
65        Self::RA,
66    ];
67}
68
69impl TryFrom<char> for Rank {
70    type Error = ParseError;
71
72    fn try_from(c: char) -> Result<Self, Self::Error> {
73        match c {
74            '2' => Ok(Self::R2),
75            '3' => Ok(Self::R3),
76            '4' => Ok(Self::R4),
77            '5' => Ok(Self::R5),
78            '6' => Ok(Self::R6),
79            '7' => Ok(Self::R7),
80            '8' => Ok(Self::R8),
81            '9' => Ok(Self::R9),
82            'T' | 't' => Ok(Self::RT),
83            'J' | 'j' => Ok(Self::RJ),
84            'Q' | 'q' => Ok(Self::RQ),
85            'K' | 'k' => Ok(Self::RK),
86            'A' | 'a' => Ok(Self::RA),
87
88            _ => Err(ParseError::InvalidRank(c.into())),
89        }
90    }
91}
92
93impl FromStr for Rank {
94    type Err = ParseError;
95
96    fn from_str(s: &str) -> Result<Self, Self::Err> {
97        let mut cs = s.chars().filter(|c| !c.is_whitespace());
98
99        if let Some(c) = cs.next() {
100            if let Ok(r) = Self::try_from(c) {
101                if cs.next().is_none() {
102                    return Ok(r);
103                }
104            }
105        }
106
107        Err(ParseError::InvalidRank(s.into()))
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    impl Arbitrary for Rank {
116        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
117            *g.choose(&Self::ARR_ALL).unwrap()
118        }
119    }
120
121    #[test]
122    fn test_consts() {
123        assert_eq!(
124            Rank::ARR_ALL,
125            [
126                Rank::R2,
127                Rank::R3,
128                Rank::R4,
129                Rank::R5,
130                Rank::R6,
131                Rank::R7,
132                Rank::R8,
133                Rank::R9,
134                Rank::RT,
135                Rank::RJ,
136                Rank::RQ,
137                Rank::RK,
138                Rank::RA,
139            ]
140        );
141    }
142
143    #[test]
144    fn test_as_int() {
145        assert_eq!(Rank::R2 as i8, 0);
146        assert_eq!(Rank::R3 as i8, 1);
147        assert_eq!(Rank::R4 as i8, 2);
148        assert_eq!(Rank::R5 as i8, 3);
149        assert_eq!(Rank::R6 as i8, 4);
150        assert_eq!(Rank::R7 as i8, 5);
151        assert_eq!(Rank::R8 as i8, 6);
152        assert_eq!(Rank::R9 as i8, 7);
153        assert_eq!(Rank::RT as i8, 8);
154        assert_eq!(Rank::RJ as i8, 9);
155        assert_eq!(Rank::RQ as i8, 10);
156        assert_eq!(Rank::RK as i8, 11);
157        assert_eq!(Rank::RA as i8, 12);
158    }
159
160    #[test]
161    fn test_from_char() {
162        assert_eq!(Ok(Rank::R2), '2'.try_into());
163        assert_eq!(Ok(Rank::R3), '3'.try_into());
164        assert_eq!(Ok(Rank::R4), '4'.try_into());
165        assert_eq!(Ok(Rank::R5), '5'.try_into());
166        assert_eq!(Ok(Rank::R6), '6'.try_into());
167        assert_eq!(Ok(Rank::R7), '7'.try_into());
168        assert_eq!(Ok(Rank::R8), '8'.try_into());
169        assert_eq!(Ok(Rank::R9), '9'.try_into());
170
171        assert_eq!(Ok(Rank::RT), 'T'.try_into());
172        assert_eq!(Ok(Rank::RJ), 'J'.try_into());
173        assert_eq!(Ok(Rank::RQ), 'Q'.try_into());
174        assert_eq!(Ok(Rank::RK), 'K'.try_into());
175        assert_eq!(Ok(Rank::RA), 'A'.try_into());
176
177        assert_eq!(Ok(Rank::RT), 't'.try_into());
178        assert_eq!(Ok(Rank::RJ), 'j'.try_into());
179        assert_eq!(Ok(Rank::RQ), 'q'.try_into());
180        assert_eq!(Ok(Rank::RK), 'k'.try_into());
181        assert_eq!(Ok(Rank::RA), 'a'.try_into());
182
183        assert_eq!(
184            Err(ParseError::InvalidRank("?".into())),
185            Rank::try_from('?')
186        );
187    }
188
189    #[test]
190    fn test_from_str() {
191        assert_eq!(Ok(Rank::R2), " 2 ".parse());
192        assert_eq!(
193            Err(ParseError::InvalidRank("23".into())),
194            "23".parse::<Rank>()
195        );
196        assert!("".parse::<Rank>().is_err());
197        assert!("?".parse::<Rank>().is_err());
198    }
199
200    #[test]
201    fn test_to_string() {
202        assert_eq!("2", &Rank::R2.to_string());
203        assert_eq!("3", &Rank::R3.to_string());
204        assert_eq!("4", &Rank::R4.to_string());
205        assert_eq!("5", &Rank::R5.to_string());
206        assert_eq!("6", &Rank::R6.to_string());
207        assert_eq!("7", &Rank::R7.to_string());
208        assert_eq!("8", &Rank::R8.to_string());
209        assert_eq!("9", &Rank::R9.to_string());
210        assert_eq!("T", &Rank::RT.to_string());
211        assert_eq!("J", &Rank::RJ.to_string());
212        assert_eq!("Q", &Rank::RQ.to_string());
213        assert_eq!("K", &Rank::RK.to_string());
214        assert_eq!("A", &Rank::RA.to_string());
215    }
216}