better_profanity/
charset.rs1use rustc_hash::FxHashSet;
2
3#[derive(Clone, Debug)]
6pub struct CharSet {
7 bmp: Box<[u64]>,
8 astral: FxHashSet<char>,
9 spaces: FxHashSet<char>,
10 len: usize,
11}
12
13impl CharSet {
14 pub fn new(chars: impl IntoIterator<Item = char>, is_space: impl Fn(char) -> bool) -> Self {
16 let mut set = CharSet {
17 bmp: vec![0; 0x10000 / 64].into_boxed_slice(),
18 astral: FxHashSet::default(),
19 spaces: FxHashSet::default(),
20 len: 0,
21 };
22 for c in chars {
23 if set.contains(c) {
24 continue;
25 }
26 set.len += 1;
27 let code = c as usize;
28 if code < 0x10000 {
29 set.bmp[code / 64] |= 1 << (code % 64);
30 } else {
31 set.astral.insert(c);
32 }
33 if is_space(c) {
34 set.spaces.insert(c);
35 }
36 }
37 set
38 }
39
40 #[inline]
41 pub fn contains(&self, c: char) -> bool {
42 let code = c as usize;
43 if code < 0x10000 {
44 self.bmp[code / 64] & (1 << (code % 64)) != 0
45 } else {
46 self.astral.contains(&c)
47 }
48 }
49
50 pub fn len(&self) -> usize {
51 self.len
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.len == 0
56 }
57
58 pub(crate) fn strips_to_empty(&self, s: &[char]) -> bool {
60 s.iter().all(|c| self.spaces.contains(c))
61 }
62}