open_pql/range_parser/ast/
rank.rs

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        // guaranteed unreachable by lexer
256        assert![Rank::from_token('?', (0, 1)).is_err()];
257    }
258}