1use super::*;
2
3macro_rules! union {
4 ($single:ident) => {
5 PQLType::$single.bits()
6 };
7 ($first:ident, $($rest:ident),+) => {
8 PQLType::$first.bits() | union!($($rest),+)
9 };
10}
11
12bitflags! {
13 #[derive(Clone, Copy, Debug, PartialEq, Eq, Display)]
14 pub struct PQLType: u32 {
15 const BOARDRANGE = 1;
16 const BOOLEAN = 1 << 1;
17 const CARD = 1 << 2;
18 const CARDCOUNT = 1 << 3;
19 const DOUBLE = 1 << 4;
20 const EQUITY = union!(DOUBLE);
21 const FLOPHANDCATEGORY = 1 << 6;
22 const FRACTION = 1 << 7;
23 const HANDRANKING = 1 << 8;
24 const HANDTYPE = 1 << 9;
25 const HIRATING = 1 << 10;
26 const INTEGER = union!(LONG);
27 const LONG = 1 << 12;
28 const LORATING = 1 << 13;
29 const NUMERIC = union!(CARDCOUNT, LONG, DOUBLE, FRACTION);
30 const PLAYER = 1 << 15;
31 const PLAYERCOUNT = union!(CARDCOUNT);
32 const RANGE = 1 << 17;
33 const RANK = 1 << 18;
34 const RANKSET = 1 << 19;
35 const STREET = 1 << 20;
36 const STRING = 1 << 21;
37 }
38}
39
40impl PQLType {
41 pub const fn is_num(self) -> bool {
42 Self::NUMERIC.contains(self)
43 }
44
45 pub const fn is_concrete(self) -> bool {
46 self.bits().is_power_of_two()
47 }
48}
49
50impl From<ast::SelectorKind> for PQLType {
51 fn from(sel: ast::SelectorKind) -> Self {
52 match sel {
53 ast::SelectorKind::Avg => Self::NUMERIC,
54 ast::SelectorKind::Count => Self::BOOLEAN,
55 ast::SelectorKind::Max | ast::SelectorKind::Min => {
56 Self::NUMERIC
57 | Self::FLOPHANDCATEGORY
58 | Self::HANDTYPE
59 | Self::HIRATING
60 | Self::RANK
61 }
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::*;
70
71 #[test]
72 fn test_type_alias() {
73 assert_eq!(PQLType::PLAYERCOUNT, PQLType::CARDCOUNT);
74 assert_eq!(PQLType::INTEGER, PQLType::LONG);
75 assert_eq!(PQLType::EQUITY, PQLType::DOUBLE);
76 }
77
78 #[test]
79 fn test_type_num() {
80 for tp in [
81 PQLType::PLAYERCOUNT,
82 PQLType::CARDCOUNT,
83 PQLType::INTEGER,
84 PQLType::LONG,
85 PQLType::EQUITY,
86 PQLType::DOUBLE,
87 PQLType::FRACTION,
88 ] {
89 assert!(PQLType::NUMERIC.contains(tp));
90 }
91 }
92
93 #[test]
94 fn test_type_for_selector() {
95 use ast::SelectorKind::*;
96 fn assert_match(sel: ast::SelectorKind, kind: PQLType) {
97 assert!(PQLType::from(sel).contains(kind));
98 }
99 fn assert_match_max_min(kind: PQLType) {
100 assert_match(Max, kind);
101 assert_match(Min, kind);
102 }
103
104 assert_match(Avg, PQLType::CARDCOUNT);
105 assert_match(Avg, PQLType::LONG);
106 assert_match(Avg, PQLType::FRACTION);
107 assert_match(Avg, PQLType::DOUBLE);
108
109 assert_match(Count, PQLType::BOOLEAN);
110
111 assert_match_max_min(PQLType::CARDCOUNT);
112 assert_match_max_min(PQLType::LONG);
113 assert_match_max_min(PQLType::FRACTION);
114 assert_match_max_min(PQLType::DOUBLE);
115 assert_match_max_min(PQLType::FLOPHANDCATEGORY);
116 assert_match_max_min(PQLType::HANDTYPE);
117 assert_match_max_min(PQLType::HIRATING);
118 assert_match_max_min(PQLType::RANK);
119 }
120}