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(test)]
84mod tests {
85    use super::{
86        super::{
87            super::tests::parse_card as p, RangeCard as C, Rank,
88            RankConst as RC, RankVar as RV,
89        },
90        *,
91    };
92
93    impl quickcheck::Arbitrary for Const {
94        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
95            *g.choose(&[
96                Self::R2,
97                Self::R3,
98                Self::R4,
99                Self::R5,
100                Self::R6,
101                Self::R7,
102                Self::R8,
103                Self::R9,
104                Self::RT,
105                Self::RJ,
106                Self::RQ,
107                Self::RK,
108                Self::RA,
109            ])
110            .unwrap()
111        }
112    }
113
114    impl Const {
115        pub fn to_src(&self) -> String {
116            match self {
117                Self::R2 => '2',
118                Self::R3 => '3',
119                Self::R4 => '4',
120                Self::R5 => '5',
121                Self::R6 => '6',
122                Self::R7 => '7',
123                Self::R8 => '8',
124                Self::R9 => '9',
125                Self::RT => 'T',
126                Self::RJ => 'J',
127                Self::RQ => 'Q',
128                Self::RK => 'K',
129                Self::RA => 'A',
130            }
131            .to_string()
132        }
133    }
134
135    impl quickcheck::Arbitrary for Var {
136        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
137            *g.choose(&[
138                Self::RB,
139                Self::RE,
140                Self::RF,
141                Self::RG,
142                Self::RI,
143                Self::RL,
144                Self::RM,
145                Self::RN,
146                Self::RO,
147                Self::RP,
148                Self::RR,
149                Self::RU,
150                Self::RV,
151            ])
152            .unwrap()
153        }
154    }
155
156    impl Var {
157        pub fn to_src(&self) -> String {
158            match self {
159                Self::RB => 'B',
160                Self::RE => 'E',
161                Self::RF => 'F',
162                Self::RG => 'G',
163                Self::RI => 'I',
164                Self::RL => 'L',
165                Self::RM => 'M',
166                Self::RN => 'N',
167                Self::RO => 'O',
168                Self::RP => 'P',
169                Self::RR => 'R',
170                Self::RU => 'U',
171                Self::RV => 'V',
172            }
173            .to_string()
174        }
175    }
176
177    #[test]
178    fn test_rank_const_as_isize() {
179        assert_eq!(RC::R2 as isize, 0);
180        assert_eq!(RC::R3 as isize, 1);
181        assert_eq!(RC::R4 as isize, 2);
182        assert_eq!(RC::R5 as isize, 3);
183        assert_eq!(RC::R6 as isize, 4);
184        assert_eq!(RC::R7 as isize, 5);
185        assert_eq!(RC::R8 as isize, 6);
186        assert_eq!(RC::R9 as isize, 7);
187        assert_eq!(RC::RT as isize, 8);
188        assert_eq!(RC::RJ as isize, 9);
189        assert_eq!(RC::RQ as isize, 10);
190        assert_eq!(RC::RK as isize, 11);
191        assert_eq!(RC::RA as isize, 12);
192    }
193
194    #[test]
195    fn test_card_rank_const() {
196        assert_eq!(p("2"), Ok(C::CA(RC::R2)));
197        assert_eq!(p("3"), Ok(C::CA(RC::R3)));
198        assert_eq!(p("4"), Ok(C::CA(RC::R4)));
199        assert_eq!(p("5"), Ok(C::CA(RC::R5)));
200        assert_eq!(p("6"), Ok(C::CA(RC::R6)));
201        assert_eq!(p("7"), Ok(C::CA(RC::R7)));
202        assert_eq!(p("8"), Ok(C::CA(RC::R8)));
203        assert_eq!(p("9"), Ok(C::CA(RC::R9)));
204
205        assert_eq!(p("T"), Ok(C::CA(RC::RT)));
206        assert_eq!(p("J"), Ok(C::CA(RC::RJ)));
207        assert_eq!(p("Q"), Ok(C::CA(RC::RQ)));
208        assert_eq!(p("K"), Ok(C::CA(RC::RK)));
209        assert_eq!(p("A"), Ok(C::CA(RC::RA)));
210
211        assert_eq!(p("t"), Ok(C::CA(RC::RT)));
212        assert_eq!(p("j"), Ok(C::CA(RC::RJ)));
213        assert_eq!(p("q"), Ok(C::CA(RC::RQ)));
214        assert_eq!(p("k"), Ok(C::CA(RC::RK)));
215        assert_eq!(p("a"), Ok(C::CA(RC::RA)));
216    }
217
218    #[test]
219    fn test_card_rank_var() {
220        assert_eq!(p("B"), Ok(C::VA(RV::RB)));
221        assert_eq!(p("E"), Ok(C::VA(RV::RE)));
222        assert_eq!(p("F"), Ok(C::VA(RV::RF)));
223        assert_eq!(p("G"), Ok(C::VA(RV::RG)));
224        assert_eq!(p("I"), Ok(C::VA(RV::RI)));
225        assert_eq!(p("L"), Ok(C::VA(RV::RL)));
226        assert_eq!(p("M"), Ok(C::VA(RV::RM)));
227        assert_eq!(p("N"), Ok(C::VA(RV::RN)));
228        assert_eq!(p("O"), Ok(C::VA(RV::RO)));
229        assert_eq!(p("P"), Ok(C::VA(RV::RP)));
230        assert_eq!(p("R"), Ok(C::VA(RV::RR)));
231        assert_eq!(p("U"), Ok(C::VA(RV::RU)));
232        assert_eq!(p("V"), Ok(C::VA(RV::RV)));
233    }
234
235    #[test]
236    fn test_card_rank_var_lower() {
237        assert_eq!(p("b"), Ok(C::VA(RV::RB)));
238        assert_eq!(p("e"), Ok(C::VA(RV::RE)));
239        assert_eq!(p("f"), Ok(C::VA(RV::RF)));
240        assert_eq!(p("g"), Ok(C::VA(RV::RG)));
241        assert_eq!(p("i"), Ok(C::VA(RV::RI)));
242        assert_eq!(p("l"), Ok(C::VA(RV::RL)));
243        assert_eq!(p("m"), Ok(C::VA(RV::RM)));
244        assert_eq!(p("n"), Ok(C::VA(RV::RN)));
245        assert_eq!(p("o"), Ok(C::VA(RV::RO)));
246        assert_eq!(p("p"), Ok(C::VA(RV::RP)));
247        assert_eq!(p("r"), Ok(C::VA(RV::RR)));
248        assert_eq!(p("u"), Ok(C::VA(RV::RU)));
249        assert_eq!(p("v"), Ok(C::VA(RV::RV)));
250    }
251
252    #[test]
253    fn test_from_token() {
254        // guaranteed unreachable by lexer
255        assert![Rank::from_token('?', (0, 1)).is_err()];
256    }
257}