open_pql/range_parser/ast/
suit.rs

1use super::{Error, LocInfo, ResultE};
2
3#[derive(Copy, Clone, PartialEq, Eq, Debug)]
4pub enum Const {
5    S,
6    H,
7    D,
8    C,
9}
10
11#[derive(Copy, Clone, PartialEq, Eq, Debug)]
12pub enum Var {
13    W,
14    X,
15    Y,
16    Z,
17}
18
19#[derive(Copy, Clone, PartialEq, Eq, Debug)]
20pub enum Suit {
21    Const(Const),
22    Var(Var),
23}
24
25impl Suit {
26    pub(crate) fn from_token(c: char, loc: LocInfo) -> ResultE<'static, Self> {
27        match c {
28            's' | 'S' => Ok(Self::Const(Const::S)),
29            'h' | 'H' => Ok(Self::Const(Const::H)),
30            'd' | 'D' => Ok(Self::Const(Const::D)),
31            'c' | 'C' => Ok(Self::Const(Const::C)),
32
33            'w' | 'W' => Ok(Self::Var(Var::W)),
34            'x' | 'X' => Ok(Self::Var(Var::X)),
35            'y' | 'Y' => Ok(Self::Var(Var::Y)),
36            'z' | 'Z' => Ok(Self::Var(Var::Z)),
37
38            _ => Err(Error::InvalidSuit(loc).into()),
39        }
40    }
41}
42
43#[cfg_attr(coverage_nightly, coverage(off))]
44#[cfg(test)]
45pub mod tests {
46    use super::{
47        super::{
48            super::tests::parse_card as p, card::RangeCard as C, Suit,
49            SuitConst as SC, SuitVar as SV,
50        },
51        *,
52    };
53
54    impl quickcheck::Arbitrary for Const {
55        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
56            *g.choose(&[Self::S, Self::H, Self::D, Self::C]).unwrap()
57        }
58    }
59
60    impl Const {
61        pub fn to_src(&self) -> String {
62            match self {
63                Self::S => 's',
64                Self::H => 'h',
65                Self::D => 'd',
66                Self::C => 'c',
67            }
68            .to_string()
69        }
70    }
71
72    impl quickcheck::Arbitrary for Var {
73        fn arbitrary(g: &mut quickcheck::Gen) -> Self {
74            *g.choose(&[Self::W, Self::X, Self::Y, Self::Z]).unwrap()
75        }
76    }
77
78    impl Var {
79        pub fn to_src(&self) -> String {
80            match self {
81                Self::W => 'w',
82                Self::X => 'x',
83                Self::Y => 'y',
84                Self::Z => 'z',
85            }
86            .to_string()
87        }
88    }
89
90    #[test]
91    fn test_card_suit_const() {
92        assert_eq!(p("S"), Ok(C::AC(SC::S)));
93        assert_eq!(p("H"), Ok(C::AC(SC::H)));
94        assert_eq!(p("D"), Ok(C::AC(SC::D)));
95        assert_eq!(p("C"), Ok(C::AC(SC::C)));
96
97        assert_eq!(p("s"), Ok(C::AC(SC::S)));
98        assert_eq!(p("h"), Ok(C::AC(SC::H)));
99        assert_eq!(p("d"), Ok(C::AC(SC::D)));
100        assert_eq!(p("c"), Ok(C::AC(SC::C)));
101    }
102
103    #[test]
104    fn test_card_suit_var() {
105        assert_eq!(p("W"), Ok(C::AV(SV::W)));
106        assert_eq!(p("X"), Ok(C::AV(SV::X)));
107        assert_eq!(p("Y"), Ok(C::AV(SV::Y)));
108        assert_eq!(p("Z"), Ok(C::AV(SV::Z)));
109
110        assert_eq!(p("w"), Ok(C::AV(SV::W)));
111        assert_eq!(p("x"), Ok(C::AV(SV::X)));
112        assert_eq!(p("y"), Ok(C::AV(SV::Y)));
113        assert_eq!(p("z"), Ok(C::AV(SV::Z)));
114    }
115
116    #[test]
117    fn test_from_token() {
118        // unreachable
119        assert![Suit::from_token('?', (0, 1)).is_err()];
120    }
121}