Skip to main content

saphyr_parser/
char_traits.rs

1//! Holds functions to determine if a character belongs to a specific character set.
2
3/// Check whether the character is nil (`\0`).
4#[inline]
5#[must_use]
6pub fn is_z(c: char) -> bool {
7    c == '\0'
8}
9
10/// Check whether the character is a line break (`\r` or `\n`).
11#[inline]
12#[must_use]
13pub fn is_break(c: char) -> bool {
14    c == '\n' || c == '\r'
15}
16
17/// Check whether the character is nil or a line break (`\0`, `\r`, `\n`).
18#[inline]
19#[must_use]
20pub fn is_breakz(c: char) -> bool {
21    is_break(c) || is_z(c)
22}
23
24/// Check whether the character is a whitespace (` ` or `\t`).
25#[inline]
26#[must_use]
27pub fn is_blank(c: char) -> bool {
28    c == ' ' || c == '\t'
29}
30
31/// Check whether the character is nil, a linebreak or a whitespace.
32///
33/// `\0`, ` `, `\t`, `\n`, `\r`
34#[inline]
35#[must_use]
36pub fn is_blank_or_breakz(c: char) -> bool {
37    is_blank(c) || is_breakz(c)
38}
39
40/// Check whether the character is an ascii digit.
41#[inline]
42#[must_use]
43pub fn is_digit(c: char) -> bool {
44    c.is_ascii_digit()
45}
46
47/// Check whether the character is a digit, letter, `_` or `-`.
48#[inline]
49#[must_use]
50pub fn is_alpha(c: char) -> bool {
51    matches!(c, '0'..='9' | 'a'..='z' | 'A'..='Z' | '_' | '-')
52}
53
54/// Check whether the character is a hexadecimal character (case insensitive).
55#[inline]
56#[must_use]
57pub fn is_hex(c: char) -> bool {
58    c.is_ascii_digit() || ('a'..='f').contains(&c) || ('A'..='F').contains(&c)
59}
60
61/// Convert the hexadecimal digit to an integer.
62#[inline]
63#[must_use]
64pub fn as_hex(c: char) -> u32 {
65    match c {
66        '0'..='9' => (c as u32) - ('0' as u32),
67        'a'..='f' => (c as u32) - ('a' as u32) + 10,
68        'A'..='F' => (c as u32) - ('A' as u32) + 10,
69        _ => unreachable!(),
70    }
71}
72
73/// Check whether the character is a YAML flow character (one of `,[]{}`).
74#[inline]
75#[must_use]
76pub fn is_flow(c: char) -> bool {
77    matches!(c, ',' | '[' | ']' | '{' | '}')
78}
79
80/// Check whether the character is the BOM character.
81#[inline]
82#[must_use]
83pub fn is_bom(c: char) -> bool {
84    c == '\u{FEFF}'
85}
86
87/// Check whether the character is a YAML non-breaking character, that is, not nil, a line break,
88/// or the BOM character.
89#[inline]
90#[must_use]
91pub fn is_yaml_non_break(c: char) -> bool {
92    // TODO(ethiraric, 28/12/2023): is_printable
93    !is_breakz(c) && !is_bom(c)
94}
95
96/// Check whether the character is NOT a YAML whitespace (` ` / `\t`).
97#[inline]
98#[must_use]
99pub fn is_yaml_non_space(c: char) -> bool {
100    is_yaml_non_break(c) && !is_blank(c)
101}
102
103/// Check whether the character is a valid YAML anchor name character.
104#[inline]
105#[must_use]
106pub fn is_anchor_char(c: char) -> bool {
107    is_yaml_non_space(c) && !is_flow(c)
108}
109
110/// Check whether the character is a valid word character.
111#[inline]
112#[must_use]
113pub fn is_word_char(c: char) -> bool {
114    is_alpha(c) && c != '_'
115}
116
117/// Check whether the character is a valid URI character.
118#[inline]
119#[must_use]
120pub fn is_uri_char(c: char) -> bool {
121    is_word_char(c) || "#;/?:@&=+$,_.!~*\'()[]%".contains(c)
122}
123
124/// Check whether the character is a valid tag character.
125#[inline]
126#[must_use]
127pub fn is_tag_char(c: char) -> bool {
128    is_uri_char(c) && !is_flow(c) && c != '!'
129}