iri_string/template/parser/
char.rs

1//! Characters.
2
3/// Properties of ASCII characters.
4///
5/// About `'` (single quote) being considered as a literal: see
6/// [Errata ID 6937](https://www.rfc-editor.org/errata/eid6937).
7const CHARS_TABLE: [u8; 128] = [
8    0b_0000_0000, // NUL
9    0b_0000_0000, // SOH
10    0b_0000_0000, // STX
11    0b_0000_0000, // ETX
12    0b_0000_0000, // EOT
13    0b_0000_0000, // ENQ
14    0b_0000_0000, // ACK
15    0b_0000_0000, // BEL
16    0b_0000_0000, // BS
17    0b_0000_0000, // HT
18    0b_0000_0000, // LF
19    0b_0000_0000, // VT
20    0b_0000_0000, // FF
21    0b_0000_0000, // CR
22    0b_0000_0000, // SO
23    0b_0000_0000, // SI
24    0b_0000_0000, // DLE
25    0b_0000_0000, // DC1
26    0b_0000_0000, // DC2
27    0b_0000_0000, // DC3
28    0b_0000_0000, // DC4
29    0b_0000_0000, // NAK
30    0b_0000_0000, // SYN
31    0b_0000_0000, // ETB
32    0b_0000_0000, // CAN
33    0b_0000_0000, // EM
34    0b_0000_0000, // SUB
35    0b_0000_0000, // ESC
36    0b_0000_0000, // FS
37    0b_0000_0000, // GS
38    0b_0000_0000, // RS
39    0b_0000_0000, // US
40    0b_0000_0000, // SPACE
41    0b_0000_0001, // !
42    0b_0000_0000, // "
43    0b_0000_0001, // #
44    0b_0000_0001, // $
45    0b_0000_0000, // %
46    0b_0000_0001, // &
47    0b_0000_0001, // '
48    0b_0000_0001, // (
49    0b_0000_0001, // )
50    0b_0000_0001, // *
51    0b_0000_0001, // +
52    0b_0000_0001, // ,
53    0b_0000_0001, // -
54    0b_0000_0101, // .
55    0b_0000_0001, // /
56    0b_0000_0111, // 0
57    0b_0000_0111, // 1
58    0b_0000_0111, // 2
59    0b_0000_0111, // 3
60    0b_0000_0111, // 4
61    0b_0000_0111, // 5
62    0b_0000_0111, // 6
63    0b_0000_0111, // 7
64    0b_0000_0111, // 8
65    0b_0000_0111, // 9
66    0b_0000_0001, // :
67    0b_0000_0001, // ;
68    0b_0000_0000, // <
69    0b_0000_0001, // =
70    0b_0000_0000, // >
71    0b_0000_0001, // ?
72    0b_0000_0001, // @
73    0b_0000_0111, // A
74    0b_0000_0111, // B
75    0b_0000_0111, // C
76    0b_0000_0111, // D
77    0b_0000_0111, // E
78    0b_0000_0111, // F
79    0b_0000_0111, // G
80    0b_0000_0111, // H
81    0b_0000_0111, // I
82    0b_0000_0111, // J
83    0b_0000_0111, // K
84    0b_0000_0111, // L
85    0b_0000_0111, // M
86    0b_0000_0111, // N
87    0b_0000_0111, // O
88    0b_0000_0111, // P
89    0b_0000_0111, // Q
90    0b_0000_0111, // R
91    0b_0000_0111, // S
92    0b_0000_0111, // T
93    0b_0000_0111, // U
94    0b_0000_0111, // V
95    0b_0000_0111, // W
96    0b_0000_0111, // X
97    0b_0000_0111, // Y
98    0b_0000_0111, // Z
99    0b_0000_0001, // [
100    0b_0000_0000, // \
101    0b_0000_0001, // ]
102    0b_0000_0000, // ^
103    0b_0000_0111, // _
104    0b_0000_0000, // `
105    0b_0000_0111, // a
106    0b_0000_0111, // b
107    0b_0000_0111, // c
108    0b_0000_0111, // d
109    0b_0000_0111, // e
110    0b_0000_0111, // f
111    0b_0000_0111, // g
112    0b_0000_0111, // h
113    0b_0000_0111, // i
114    0b_0000_0111, // j
115    0b_0000_0111, // k
116    0b_0000_0111, // l
117    0b_0000_0111, // m
118    0b_0000_0111, // n
119    0b_0000_0111, // o
120    0b_0000_0111, // p
121    0b_0000_0111, // q
122    0b_0000_0111, // r
123    0b_0000_0111, // s
124    0b_0000_0111, // t
125    0b_0000_0111, // u
126    0b_0000_0111, // v
127    0b_0000_0111, // w
128    0b_0000_0111, // x
129    0b_0000_0111, // y
130    0b_0000_0111, // z
131    0b_0000_0000, // {
132    0b_0000_0000, // |
133    0b_0000_0000, // }
134    0b_0000_0001, // ~
135    0b_0000_0000, // DEL
136];
137
138/// A mask to test whether the character matches `literals` rule defined in [RFC 6570].
139///
140/// [RFC 6570]: https://www.rfc-editor.org/rfc/rfc6570.html#section-2.1
141const CHARS_TABLE_MASK_LITERAL: u8 = 1 << 0;
142
143/// A mask to test whether the character matches `varchar` rule defined in [RFC 6570].
144///
145/// [RFC 6570]: https://www.rfc-editor.org/rfc/rfc6570.html#section-2.3
146const CHARS_TABLE_MASK_VARCHAR_START: u8 = 1 << 1;
147
148/// A mask to test whether the character matches `varchar` rule defined in [RFC 6570] or a period.
149///
150/// [RFC 6570]: https://www.rfc-editor.org/rfc/rfc6570.html#section-2.3
151const CHARS_TABLE_MASK_VARCHAR_CONTINUE: u8 = 1 << 2;
152
153/// Returns true if the given ASCII character is allowed in a literal string.
154///
155/// # Precondition
156///
157/// The given byte should be an ASCII character, i.e. should be less than 128.
158#[inline]
159#[must_use]
160pub(super) const fn is_ascii_literal_char(c: u8) -> bool {
161    (CHARS_TABLE[c as usize] & CHARS_TABLE_MASK_LITERAL) != 0
162}
163
164/// Returns true if the given ASCII character is allowed as the beginning of the `varname`.
165///
166/// Note that this does not return true for `%` character. It is caller's
167/// responsibility to test validity of percent-encoded triplets.
168///
169/// # Precondition
170///
171/// The given byte should be an ASCII character, i.e. should be less than 128.
172#[inline]
173#[must_use]
174pub(super) const fn is_ascii_varchar_start(c: u8) -> bool {
175    (CHARS_TABLE[c as usize] & CHARS_TABLE_MASK_VARCHAR_START) != 0
176}
177
178/// Returns true if the given ASCII character is allowed as the non-beginning of the `varname`.
179///
180/// Note that this does not return true for `%` character. It is caller's
181/// responsibility to test validity of percent-encoded triplets.
182///
183/// # Precondition
184///
185/// The given byte should be an ASCII character, i.e. should be less than 128.
186#[inline]
187#[must_use]
188pub(super) const fn is_ascii_varchar_continue(c: u8) -> bool {
189    (CHARS_TABLE[c as usize] & CHARS_TABLE_MASK_VARCHAR_CONTINUE) != 0
190}