arrow_parser/
char.rs

1use core::ops::RangeInclusive;
2use lazy_static::lazy_static;
3
4#[derive(Clone)]
5pub struct CharFilter {
6  table: [bool; 256],
7}
8
9impl CharFilter {
10  pub fn new() -> CharFilter {
11    CharFilter {
12      table: [false; 256],
13    }
14  }
15
16  pub fn add_char(&mut self, c: u8) -> () {
17    self.table[c as usize] = true;
18  }
19
20  pub fn add_chars(&mut self, chars: RangeInclusive<u8>) -> () {
21    for c in chars {
22      self.table[c as usize] = true;
23    }
24  }
25
26  pub fn add_chars_from_slice(&mut self, chars: &[u8]) -> () {
27    for c in chars {
28      self.table[*c as usize] = true;
29    }
30  }
31
32  pub fn clone(&self) -> CharFilter {
33    CharFilter {
34      table: self.table.clone(),
35    }
36  }
37
38  pub fn invert(&mut self) -> () {
39    for i in 0..256 {
40      self.table[i] = !self.table[i];
41    }
42  }
43
44  pub fn has(&self, c: u8) -> bool {
45    unsafe { *self.table.get_unchecked(c as usize) }
46  }
47
48  pub fn iter(&self) -> impl Iterator<Item = u8> + '_ {
49    self
50      .table
51      .iter()
52      .enumerate()
53      .filter(|(_, e)| **e)
54      .map(|(c, _)| c as u8)
55  }
56}
57
58pub const ID_START_CHARSTR: &'static [u8] =
59  b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
60pub const ID_CONTINUE_CHARSTR: &'static [u8] =
61  b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
62
63lazy_static! {
64  pub static ref DIGIT: CharFilter = {
65    let mut filter = CharFilter::new();
66    filter.add_chars(b'0'..=b'9');
67    filter
68  };
69
70  pub static ref DIGIT_BIN: CharFilter = {
71    let mut filter = CharFilter::new();
72    filter.add_chars(b'0'..=b'1');
73    filter
74  };
75
76  pub static ref DIGIT_HEX: CharFilter = {
77    let mut filter = CharFilter::new();
78    filter.add_chars(b'0'..=b'9');
79    filter.add_chars(b'a'..=b'f');
80    filter.add_chars(b'A'..=b'F');
81    filter
82  };
83
84  pub static ref DIGIT_OCT: CharFilter = {
85    let mut filter = CharFilter::new();
86    filter.add_chars(b'0'..=b'8');
87    filter
88  };
89
90  pub static ref ID_START: CharFilter = {
91    let mut filter = CharFilter::new();
92    filter.add_chars_from_slice(&ID_START_CHARSTR);
93    filter
94  };
95
96  pub static ref ID_CONTINUE: CharFilter = {
97    let mut filter = ID_START.clone();
98    filter.add_chars(b'0'..=b'9');
99    filter
100  };
101
102  pub static ref WHITESPACE: CharFilter = {
103    let mut filter = CharFilter::new();
104    // Horizontal tab.
105    filter.add_char(b'\x09');
106    // Line feed.
107    filter.add_char(b'\x0a');
108    // Vertical tab.
109    filter.add_char(b'\x0b');
110    // Form feed.
111    filter.add_char(b'\x0c');
112    // Carriage return.
113    filter.add_char(b'\x0d');
114    // Space.
115    filter.add_char(b'\x20');
116    filter
117  };
118}