granit_parser/
char_traits.rs1#[inline]
5#[must_use]
6pub fn is_z(c: char) -> bool {
7 c == '\0'
8}
9
10#[inline]
12#[must_use]
13pub fn is_break(c: char) -> bool {
14 c == '\n' || c == '\r'
15}
16
17#[inline]
19#[must_use]
20pub fn is_breakz(c: char) -> bool {
21 is_break(c) || is_z(c)
22}
23
24#[inline]
26#[must_use]
27pub fn is_blank(c: char) -> bool {
28 c == ' ' || c == '\t'
29}
30
31#[inline]
35#[must_use]
36pub fn is_blank_or_breakz(c: char) -> bool {
37 is_blank(c) || is_breakz(c)
38}
39
40#[inline]
42#[must_use]
43pub fn is_digit(c: char) -> bool {
44 c.is_ascii_digit()
45}
46
47#[inline]
55#[must_use]
56pub fn is_alpha(c: char) -> bool {
57 matches!(c, '0'..='9' | 'a'..='z' | 'A'..='Z' | '_' | '-')
58}
59
60#[inline]
62#[must_use]
63pub fn is_hex(c: char) -> bool {
64 c.is_ascii_digit() || ('a'..='f').contains(&c) || ('A'..='F').contains(&c)
65}
66
67#[track_caller]
72#[inline]
73#[must_use]
74pub fn as_hex(c: char) -> u32 {
75 match c {
76 '0'..='9' => (c as u32) - ('0' as u32),
77 'a'..='f' => (c as u32) - ('a' as u32) + 10,
78 'A'..='F' => (c as u32) - ('A' as u32) + 10,
79 _ => unreachable!("as_hex called with a non-hexadecimal character"),
80 }
81}
82
83#[inline]
85#[must_use]
86pub fn is_flow(c: char) -> bool {
87 matches!(c, ',' | '[' | ']' | '{' | '}')
88}
89
90#[inline]
92#[must_use]
93pub fn is_bom(c: char) -> bool {
94 c == '\u{FEFF}'
95}
96
97#[inline]
99#[must_use]
100pub fn is_yaml_non_break(c: char) -> bool {
101 is_printable(c) && !is_break(c) && !is_bom(c)
102}
103
104#[inline]
106#[must_use]
107pub(crate) fn is_printable(c: char) -> bool {
108 matches!(
109 c as u32,
110 0x0009
111 | 0x000A
112 | 0x000D
113 | 0x0020..=0x007E
114 | 0x0085
115 | 0x00A0..=0xD7FF
116 | 0xE000..=0xFFFD
117 | 0x10000..=0x0010_FFFF
118 )
119}
120
121#[inline]
123#[must_use]
124pub fn is_yaml_non_space(c: char) -> bool {
125 is_yaml_non_break(c) && !is_blank(c)
126}
127
128#[inline]
130#[must_use]
131pub fn is_anchor_char(c: char) -> bool {
132 is_yaml_non_space(c) && !is_flow(c) && !is_z(c)
133}
134
135#[inline]
141#[must_use]
142pub fn is_word_char(c: char) -> bool {
143 is_alpha(c) && c != '_'
144}
145
146#[inline]
148#[must_use]
149pub fn is_uri_char(c: char) -> bool {
150 is_word_char(c) || "#;/?:@&=+$,_.!~*\'()[]%".contains(c)
151}
152
153#[inline]
155#[must_use]
156pub fn is_tag_char(c: char) -> bool {
157 is_uri_char(c) && !is_flow(c) && c != '!'
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163
164 #[test]
165 fn printable_ranges_include_private_and_supplementary_planes() {
166 assert!(is_printable('\u{E000}'));
167 assert!(is_printable('\u{10FFFF}'));
168 assert!(is_yaml_non_break('\u{10000}'));
169 assert!(!is_yaml_non_break('\u{FEFF}'));
170 assert!(!is_yaml_non_break('\n'));
171 }
172
173 #[test]
174 fn word_uri_and_tag_character_sets_are_distinct() {
175 assert!(is_word_char('-'));
176 assert!(!is_word_char('_'));
177 assert!(is_uri_char('_'));
178 assert!(is_uri_char('%'));
179 assert!(!is_tag_char('!'));
180 assert!(!is_tag_char('['));
181 }
182}