1pub fn is_name(name: &str) -> bool {
2 let mut c = name.chars();
4 if !c.next().is_some_and(is_name_start_char) {
5 return false;
6 }
7 c.all(is_name_char)
8}
9
10pub fn is_nc_name(name: &str) -> bool {
11 is_name(name) && !name.contains(':')
13}
14
15pub fn is_name_start_char(c: char) -> bool {
16 matches!(c,
18 ':'
19 | 'A'..='Z'
20 | '_'
21 | 'a'..='z'
22 | '\u{00C0}'..='\u{00D6}'
23 | '\u{00D8}'..='\u{00F6}'
24 | '\u{00F8}'..='\u{02FF}'
25 | '\u{0370}'..='\u{037D}'
26 | '\u{037F}'..='\u{1FFF}'
27 | '\u{200C}'..='\u{200D}'
28 | '\u{2070}'..='\u{218F}'
29 | '\u{2C00}'..='\u{2FEF}'
30 | '\u{3001}'..='\u{D7FF}'
31 | '\u{F900}'..='\u{FDCF}'
32 | '\u{FDF0}'..='\u{FFFD}'
33 | '\u{10000}'..='\u{EFFFF}')
34}
35
36pub fn is_name_char(c: char) -> bool {
37 is_name_start_char(c)
39 || matches!(c, '-' | '.' | '0'..='9' | '\u{B7}' | '\u{0300}'..='\u{036F}' | '\u{203F}'..='\u{2040}')
40}