openpql_range_parser/ast/
card.rs

1use super::{
2    CardRank, CardSuit, Display, From, RankConst, RankVar, SuitConst, SuitVar,
3};
4
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Display)]
6pub enum RangeCard {
7    #[display("{_0}{_1}")]
8    CC(RankConst, SuitConst),
9    #[display("{_0}{_1}")]
10    CV(RankConst, SuitVar),
11    #[display("{_0}")]
12    CA(RankConst),
13    #[display("{_0}{_1}")]
14    VC(RankVar, SuitConst),
15    #[display("{_0}{_1}")]
16    VV(RankVar, SuitVar),
17    #[display("{_0}")]
18    VA(RankVar),
19    #[display("{_0}")]
20    AC(SuitConst),
21    #[display("{_0}")]
22    AV(SuitVar),
23    #[display("*")]
24    AA,
25}
26
27impl From<(CardRank, CardSuit)> for RangeCard {
28    fn from(t: (CardRank, CardSuit)) -> Self {
29        match t {
30            (CardRank::Const(r), CardSuit::Const(s)) => Self::CC(r, s),
31            (CardRank::Const(r), CardSuit::Var(s)) => Self::CV(r, s),
32            (CardRank::Var(r), CardSuit::Const(s)) => Self::VC(r, s),
33            (CardRank::Var(r), CardSuit::Var(s)) => Self::VV(r, s),
34            (CardRank::Any, CardSuit::Const(s)) => Self::AC(s),
35            (CardRank::Any, CardSuit::Var(s)) => Self::AV(s),
36        }
37    }
38}
39
40impl From<CardRank> for RangeCard {
41    fn from(r: CardRank) -> Self {
42        match r {
43            CardRank::Const(c) => Self::CA(c),
44            CardRank::Var(v) => Self::VA(v),
45            CardRank::Any => Self::AA,
46        }
47    }
48}
49
50impl From<CardSuit> for RangeCard {
51    fn from(s: CardSuit) -> Self {
52        match s {
53            CardSuit::Const(c) => Self::AC(c),
54            CardSuit::Var(v) => Self::AV(v),
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use crate::*;
63
64    impl Arbitrary for RangeCard {
65        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
66            match *g.choose(&[0, 1, 2, 3, 4, 5, 6, 7, 8]).unwrap() {
67                0 => Self::CC(RankConst::arbitrary(g), SuitConst::arbitrary(g)),
68                1 => Self::CV(RankConst::arbitrary(g), SuitVar::arbitrary(g)),
69                2 => Self::CA(RankConst::arbitrary(g)),
70                3 => Self::VC(RankVar::arbitrary(g), SuitConst::arbitrary(g)),
71                4 => Self::VV(RankVar::arbitrary(g), SuitVar::arbitrary(g)),
72                5 => Self::VA(RankVar::arbitrary(g)),
73                6 => Self::AC(SuitConst::arbitrary(g)),
74                7 => Self::AV(SuitVar::arbitrary(g)),
75                _ => Self::AA,
76            }
77        }
78    }
79
80    #[test]
81    fn test_card_cc() {
82        assert_range_card("As", "As");
83    }
84
85    #[test]
86    fn test_card_cv() {
87        assert_range_card("Aw", "Aw");
88    }
89
90    #[test]
91    fn test_card_ca() {
92        assert_range_card("A", "A");
93    }
94
95    #[test]
96    fn test_card_vc() {
97        assert_range_card("Bs", "Bs");
98    }
99
100    #[test]
101    fn test_card_vv() {
102        assert_range_card("Bw", "Bw");
103    }
104
105    #[test]
106    fn test_card_va() {
107        assert_range_card("B", "B");
108    }
109
110    #[test]
111    fn test_card_ac() {
112        assert_range_card("s", "s");
113        assert_range_card("*s", "s");
114    }
115
116    #[test]
117    fn test_card_av() {
118        assert_range_card("w", "w");
119        assert_range_card("*w", "w");
120    }
121
122    #[test]
123    fn test_card_aa() {
124        assert_range_card("*", "*");
125    }
126
127    #[quickcheck]
128    fn test_shortdeck(card: RangeCard) {
129        let src = card.to_string();
130        if src.chars().any(|c| ['2', '3', '4', '5'].contains(&c)) {
131            assert!(parse_card_sd(&src).is_err());
132        } else {
133            assert_eq!(Ok(card), parse_card_sd(&src));
134        }
135    }
136
137    fn assert_range_card_sd_err(s: &str, expected: Error) {
138        assert_eq!(parse_card_sd(s), Err(expected.into()));
139    }
140
141    #[test]
142    fn test_shortdeck_error() {
143        assert_range_card_sd_err("2", Error::InvalidRank((0, 1)));
144        assert_range_card_sd_err("3", Error::InvalidRank((0, 1)));
145        assert_range_card_sd_err("4", Error::InvalidRank((0, 1)));
146        assert_range_card_sd_err("5", Error::InvalidRank((0, 1)));
147    }
148}