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}