openpql_range_parser/ast/
rank.rs

1use super::{Display, Error, LocInfo, ResultE};
2
3pub type RankConst = openpql_prelude::Rank;
4
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Display)]
6pub enum RankVar {
7    #[display("B")]
8    RB,
9    #[display("E")]
10    RE,
11    #[display("F")]
12    RF,
13    #[display("G")]
14    RG,
15    #[display("I")]
16    RI,
17    #[display("L")]
18    RL,
19    #[display("M")]
20    RM,
21    #[display("N")]
22    RN,
23    #[display("O")]
24    RO,
25    #[display("P")]
26    RP,
27    #[display("R")]
28    RR,
29    #[display("U")]
30    RU,
31    #[display("V")]
32    RV,
33}
34
35#[derive(Copy, Clone, PartialEq, Eq, Debug, Display)]
36pub enum CardRank {
37    #[display("{_0}")]
38    Const(RankConst),
39    #[display("{_0}")]
40    Var(RankVar),
41    #[display("*")]
42    Any,
43}
44
45impl CardRank {
46    pub(crate) fn from_token(
47        is_shortdeck: bool,
48        c: char,
49        loc: LocInfo,
50    ) -> ResultE<'static, Self> {
51        if is_shortdeck {
52            match c {
53                '2' | '3' | '4' | '5' => {
54                    return Err(Error::InvalidRank(loc).into());
55                }
56                _ => (),
57            }
58        }
59
60        match c {
61            '*' => Ok(Self::Any),
62
63            '2' => Ok(Self::Const(RankConst::R2)),
64            '3' => Ok(Self::Const(RankConst::R3)),
65            '4' => Ok(Self::Const(RankConst::R4)),
66            '5' => Ok(Self::Const(RankConst::R5)),
67            '6' => Ok(Self::Const(RankConst::R6)),
68            '7' => Ok(Self::Const(RankConst::R7)),
69            '8' => Ok(Self::Const(RankConst::R8)),
70            '9' => Ok(Self::Const(RankConst::R9)),
71
72            'T' | 't' => Ok(Self::Const(RankConst::RT)),
73            'J' | 'j' => Ok(Self::Const(RankConst::RJ)),
74            'Q' | 'q' => Ok(Self::Const(RankConst::RQ)),
75            'K' | 'k' => Ok(Self::Const(RankConst::RK)),
76            'A' | 'a' => Ok(Self::Const(RankConst::RA)),
77
78            'B' | 'b' => Ok(Self::Var(RankVar::RB)),
79            'E' | 'e' => Ok(Self::Var(RankVar::RE)),
80            'F' | 'f' => Ok(Self::Var(RankVar::RF)),
81            'G' | 'g' => Ok(Self::Var(RankVar::RG)),
82            'I' | 'i' => Ok(Self::Var(RankVar::RI)),
83            'L' | 'l' => Ok(Self::Var(RankVar::RL)),
84            'M' | 'm' => Ok(Self::Var(RankVar::RM)),
85            'N' | 'n' => Ok(Self::Var(RankVar::RN)),
86            'O' | 'o' => Ok(Self::Var(RankVar::RO)),
87            'P' | 'p' => Ok(Self::Var(RankVar::RP)),
88            'R' | 'r' => Ok(Self::Var(RankVar::RR)),
89            'U' | 'u' => Ok(Self::Var(RankVar::RU)),
90            'V' | 'v' => Ok(Self::Var(RankVar::RV)),
91
92            _ => Err(Error::InvalidRank(loc).into()),
93        }
94    }
95}
96
97#[cfg(test)]
98#[cfg_attr(coverage_nightly, coverage(off))]
99mod tests {
100    use super::*;
101    use crate::*;
102
103    impl Arbitrary for RankVar {
104        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
105            *g.choose(&[
106                Self::RB,
107                Self::RE,
108                Self::RF,
109                Self::RG,
110                Self::RI,
111                Self::RL,
112                Self::RM,
113                Self::RN,
114                Self::RO,
115                Self::RP,
116                Self::RR,
117                Self::RU,
118                Self::RV,
119            ])
120            .unwrap()
121        }
122    }
123
124    #[test]
125    fn test_card_rank_const() {
126        assert_range_card("2", "2");
127        assert_range_card("3", "3");
128        assert_range_card("4", "4");
129        assert_range_card("5", "5");
130        assert_range_card("6", "6");
131        assert_range_card("7", "7");
132        assert_range_card("8", "8");
133        assert_range_card("9", "9");
134
135        assert_range_card("T", "T");
136        assert_range_card("J", "J");
137        assert_range_card("Q", "Q");
138        assert_range_card("K", "K");
139        assert_range_card("A", "A");
140
141        assert_range_card("t", "T");
142        assert_range_card("j", "J");
143        assert_range_card("q", "Q");
144        assert_range_card("k", "K");
145        assert_range_card("a", "A");
146    }
147
148    #[test]
149    fn test_card_rank_var() {
150        assert_range_card("B", "B");
151        assert_range_card("E", "E");
152        assert_range_card("F", "F");
153        assert_range_card("G", "G");
154        assert_range_card("I", "I");
155        assert_range_card("L", "L");
156        assert_range_card("M", "M");
157        assert_range_card("N", "N");
158        assert_range_card("O", "O");
159        assert_range_card("P", "P");
160        assert_range_card("R", "R");
161        assert_range_card("U", "U");
162        assert_range_card("V", "V");
163    }
164
165    #[test]
166    fn test_card_rank_var_lower() {
167        assert_range_card("b", "B");
168        assert_range_card("e", "E");
169        assert_range_card("f", "F");
170        assert_range_card("g", "G");
171        assert_range_card("i", "I");
172        assert_range_card("l", "L");
173        assert_range_card("m", "M");
174        assert_range_card("n", "N");
175        assert_range_card("o", "O");
176        assert_range_card("p", "P");
177        assert_range_card("r", "R");
178        assert_range_card("u", "U");
179        assert_range_card("v", "V");
180    }
181
182    #[test]
183    fn test_from_token() {
184        // guaranteed unreachable by lexer
185        assert![CardRank::from_token(false, '?', (0, 1)).is_err()];
186    }
187}