1use super::*;
2
3#[derive(
5 Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd, Hash, Display, Default,
6)]
7pub enum Rank {
8 #[default]
10 #[display("2")]
11 R2 = 0,
12 #[display("3")]
14 R3,
15 #[display("4")]
17 R4,
18 #[display("5")]
20 R5,
21 #[display("6")]
23 R6,
24 #[display("7")]
26 R7,
27 #[display("8")]
29 R8,
30 #[display("9")]
32 R9,
33 #[display("T")]
35 RT,
36 #[display("J")]
38 RJ,
39 #[display("Q")]
41 RQ,
42 #[display("K")]
44 RK,
45 #[display("A")]
47 RA,
48}
49
50impl Rank {
51 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}