1use super::{Error, LocInfo, ResultE};
2
3#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
4pub enum Const {
5 R2 = 0,
6 R3,
7 R4,
8 R5,
9 R6,
10 R7,
11 R8,
12 R9,
13 RT,
14 RJ,
15 RQ,
16 RK,
17 RA,
18}
19
20#[derive(Copy, Clone, PartialEq, Eq, Debug)]
21pub enum Var {
22 RB,
23 RE,
24 RF,
25 RG,
26 RI,
27 RL,
28 RM,
29 RN,
30 RO,
31 RP,
32 RR,
33 RU,
34 RV,
35}
36
37#[derive(Copy, Clone, PartialEq, Eq, Debug)]
38pub enum Rank {
39 Const(Const),
40 Var(Var),
41 Any,
42}
43
44impl Rank {
45 pub(crate) fn from_token(c: char, loc: LocInfo) -> ResultE<'static, Self> {
46 match c {
47 '*' => Ok(Self::Any),
48
49 '2' => Ok(Self::Const(Const::R2)),
50 '3' => Ok(Self::Const(Const::R3)),
51 '4' => Ok(Self::Const(Const::R4)),
52 '5' => Ok(Self::Const(Const::R5)),
53 '6' => Ok(Self::Const(Const::R6)),
54 '7' => Ok(Self::Const(Const::R7)),
55 '8' => Ok(Self::Const(Const::R8)),
56 '9' => Ok(Self::Const(Const::R9)),
57
58 'T' | 't' => Ok(Self::Const(Const::RT)),
59 'J' | 'j' => Ok(Self::Const(Const::RJ)),
60 'Q' | 'q' => Ok(Self::Const(Const::RQ)),
61 'K' | 'k' => Ok(Self::Const(Const::RK)),
62 'A' | 'a' => Ok(Self::Const(Const::RA)),
63
64 'B' | 'b' => Ok(Self::Var(Var::RB)),
65 'E' | 'e' => Ok(Self::Var(Var::RE)),
66 'F' | 'f' => Ok(Self::Var(Var::RF)),
67 'G' | 'g' => Ok(Self::Var(Var::RG)),
68 'I' | 'i' => Ok(Self::Var(Var::RI)),
69 'L' | 'l' => Ok(Self::Var(Var::RL)),
70 'M' | 'm' => Ok(Self::Var(Var::RM)),
71 'N' | 'n' => Ok(Self::Var(Var::RN)),
72 'O' | 'o' => Ok(Self::Var(Var::RO)),
73 'P' | 'p' => Ok(Self::Var(Var::RP)),
74 'R' | 'r' => Ok(Self::Var(Var::RR)),
75 'U' | 'u' => Ok(Self::Var(Var::RU)),
76 'V' | 'v' => Ok(Self::Var(Var::RV)),
77
78 _ => Err(Error::InvalidRank(loc).into()),
79 }
80 }
81}
82
83#[cfg_attr(coverage_nightly, coverage(off))]
84#[cfg(test)]
85mod tests {
86 use super::{
87 super::{
88 super::tests::parse_card as p, RangeCard as C, Rank,
89 RankConst as RC, RankVar as RV,
90 },
91 *,
92 };
93
94 impl quickcheck::Arbitrary for Const {
95 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
96 *g.choose(&[
97 Self::R2,
98 Self::R3,
99 Self::R4,
100 Self::R5,
101 Self::R6,
102 Self::R7,
103 Self::R8,
104 Self::R9,
105 Self::RT,
106 Self::RJ,
107 Self::RQ,
108 Self::RK,
109 Self::RA,
110 ])
111 .unwrap()
112 }
113 }
114
115 impl Const {
116 pub fn to_src(&self) -> String {
117 match self {
118 Self::R2 => '2',
119 Self::R3 => '3',
120 Self::R4 => '4',
121 Self::R5 => '5',
122 Self::R6 => '6',
123 Self::R7 => '7',
124 Self::R8 => '8',
125 Self::R9 => '9',
126 Self::RT => 'T',
127 Self::RJ => 'J',
128 Self::RQ => 'Q',
129 Self::RK => 'K',
130 Self::RA => 'A',
131 }
132 .to_string()
133 }
134 }
135
136 impl quickcheck::Arbitrary for Var {
137 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
138 *g.choose(&[
139 Self::RB,
140 Self::RE,
141 Self::RF,
142 Self::RG,
143 Self::RI,
144 Self::RL,
145 Self::RM,
146 Self::RN,
147 Self::RO,
148 Self::RP,
149 Self::RR,
150 Self::RU,
151 Self::RV,
152 ])
153 .unwrap()
154 }
155 }
156
157 impl Var {
158 pub fn to_src(&self) -> String {
159 match self {
160 Self::RB => 'B',
161 Self::RE => 'E',
162 Self::RF => 'F',
163 Self::RG => 'G',
164 Self::RI => 'I',
165 Self::RL => 'L',
166 Self::RM => 'M',
167 Self::RN => 'N',
168 Self::RO => 'O',
169 Self::RP => 'P',
170 Self::RR => 'R',
171 Self::RU => 'U',
172 Self::RV => 'V',
173 }
174 .to_string()
175 }
176 }
177
178 #[test]
179 fn test_rank_const_as_isize() {
180 assert_eq!(RC::R2 as isize, 0);
181 assert_eq!(RC::R3 as isize, 1);
182 assert_eq!(RC::R4 as isize, 2);
183 assert_eq!(RC::R5 as isize, 3);
184 assert_eq!(RC::R6 as isize, 4);
185 assert_eq!(RC::R7 as isize, 5);
186 assert_eq!(RC::R8 as isize, 6);
187 assert_eq!(RC::R9 as isize, 7);
188 assert_eq!(RC::RT as isize, 8);
189 assert_eq!(RC::RJ as isize, 9);
190 assert_eq!(RC::RQ as isize, 10);
191 assert_eq!(RC::RK as isize, 11);
192 assert_eq!(RC::RA as isize, 12);
193 }
194
195 #[test]
196 fn test_card_rank_const() {
197 assert_eq!(p("2"), Ok(C::CA(RC::R2)));
198 assert_eq!(p("3"), Ok(C::CA(RC::R3)));
199 assert_eq!(p("4"), Ok(C::CA(RC::R4)));
200 assert_eq!(p("5"), Ok(C::CA(RC::R5)));
201 assert_eq!(p("6"), Ok(C::CA(RC::R6)));
202 assert_eq!(p("7"), Ok(C::CA(RC::R7)));
203 assert_eq!(p("8"), Ok(C::CA(RC::R8)));
204 assert_eq!(p("9"), Ok(C::CA(RC::R9)));
205
206 assert_eq!(p("T"), Ok(C::CA(RC::RT)));
207 assert_eq!(p("J"), Ok(C::CA(RC::RJ)));
208 assert_eq!(p("Q"), Ok(C::CA(RC::RQ)));
209 assert_eq!(p("K"), Ok(C::CA(RC::RK)));
210 assert_eq!(p("A"), Ok(C::CA(RC::RA)));
211
212 assert_eq!(p("t"), Ok(C::CA(RC::RT)));
213 assert_eq!(p("j"), Ok(C::CA(RC::RJ)));
214 assert_eq!(p("q"), Ok(C::CA(RC::RQ)));
215 assert_eq!(p("k"), Ok(C::CA(RC::RK)));
216 assert_eq!(p("a"), Ok(C::CA(RC::RA)));
217 }
218
219 #[test]
220 fn test_card_rank_var() {
221 assert_eq!(p("B"), Ok(C::VA(RV::RB)));
222 assert_eq!(p("E"), Ok(C::VA(RV::RE)));
223 assert_eq!(p("F"), Ok(C::VA(RV::RF)));
224 assert_eq!(p("G"), Ok(C::VA(RV::RG)));
225 assert_eq!(p("I"), Ok(C::VA(RV::RI)));
226 assert_eq!(p("L"), Ok(C::VA(RV::RL)));
227 assert_eq!(p("M"), Ok(C::VA(RV::RM)));
228 assert_eq!(p("N"), Ok(C::VA(RV::RN)));
229 assert_eq!(p("O"), Ok(C::VA(RV::RO)));
230 assert_eq!(p("P"), Ok(C::VA(RV::RP)));
231 assert_eq!(p("R"), Ok(C::VA(RV::RR)));
232 assert_eq!(p("U"), Ok(C::VA(RV::RU)));
233 assert_eq!(p("V"), Ok(C::VA(RV::RV)));
234 }
235
236 #[test]
237 fn test_card_rank_var_lower() {
238 assert_eq!(p("b"), Ok(C::VA(RV::RB)));
239 assert_eq!(p("e"), Ok(C::VA(RV::RE)));
240 assert_eq!(p("f"), Ok(C::VA(RV::RF)));
241 assert_eq!(p("g"), Ok(C::VA(RV::RG)));
242 assert_eq!(p("i"), Ok(C::VA(RV::RI)));
243 assert_eq!(p("l"), Ok(C::VA(RV::RL)));
244 assert_eq!(p("m"), Ok(C::VA(RV::RM)));
245 assert_eq!(p("n"), Ok(C::VA(RV::RN)));
246 assert_eq!(p("o"), Ok(C::VA(RV::RO)));
247 assert_eq!(p("p"), Ok(C::VA(RV::RP)));
248 assert_eq!(p("r"), Ok(C::VA(RV::RR)));
249 assert_eq!(p("u"), Ok(C::VA(RV::RU)));
250 assert_eq!(p("v"), Ok(C::VA(RV::RV)));
251 }
252
253 #[test]
254 fn test_from_token() {
255 assert![Rank::from_token('?', (0, 1)).is_err()];
257 }
258}