1use std::ops;
2
3use crate::SyntaxKind;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct TokenSet(u128);
8
9impl TokenSet {
10 #[allow(dead_code)]
11 pub(crate) const EMPTY: TokenSet = TokenSet(0);
12
13 pub(crate) const fn new(kind: SyntaxKind) -> TokenSet {
14 TokenSet(mask(kind))
15 }
16
17 pub(crate) const fn from_slice(kinds: &[SyntaxKind]) -> TokenSet {
18 let mut res = 0u128;
19 let mut i = 0;
20 while i < kinds.len() {
21 res |= mask(kinds[i]);
22 i += 1
23 }
24 TokenSet(res)
25 }
26
27 pub(crate) const fn union(self, other: TokenSet) -> TokenSet {
28 TokenSet(self.0 | other.0)
29 }
30
31 pub(crate) const fn contains(&self, kind: SyntaxKind) -> bool {
32 self.0 & mask(kind) != 0
33 }
34}
35
36const fn mask(kind: SyntaxKind) -> u128 {
37 1u128 << (kind as usize)
38}
39
40impl ops::BitOr for SyntaxKind {
41 type Output = TokenSet;
42
43 fn bitor(self, rhs: Self) -> Self::Output {
44 TokenSet(mask(self) | mask(rhs))
45 }
46}
47
48impl ops::BitOr<SyntaxKind> for TokenSet {
49 type Output = TokenSet;
50
51 fn bitor(self, rhs: SyntaxKind) -> Self::Output {
52 self.union(TokenSet(mask(rhs)))
53 }
54}
55
56impl ops::BitOr<TokenSet> for SyntaxKind {
57 type Output = TokenSet;
58
59 fn bitor(self, rhs: TokenSet) -> Self::Output {
60 TokenSet(mask(self)).union(rhs)
61 }
62}
63
64impl ops::BitOr<TokenSet> for TokenSet {
65 type Output = TokenSet;
66
67 fn bitor(self, rhs: TokenSet) -> Self::Output {
68 self.union(rhs)
69 }
70}
71
72impl ops::BitOr<SyntaxKind> for () {
73 type Output = TokenSet;
74
75 fn bitor(self, rhs: SyntaxKind) -> Self::Output {
76 TokenSet::new(rhs)
77 }
78}
79
80impl ops::BitOr<()> for SyntaxKind {
81 type Output = TokenSet;
82
83 fn bitor(self, (): ()) -> Self::Output {
84 TokenSet::new(self)
85 }
86}