script/dom/bindings/
xmlname.rs1pub(crate) fn is_valid_start(c: char) -> bool {
10 matches!(c, ':' |
11 'A'..='Z' |
12 '_' |
13 'a'..='z' |
14 '\u{C0}'..='\u{D6}' |
15 '\u{D8}'..='\u{F6}' |
16 '\u{F8}'..='\u{2FF}' |
17 '\u{370}'..='\u{37D}' |
18 '\u{37F}'..='\u{1FFF}' |
19 '\u{200C}'..='\u{200D}' |
20 '\u{2070}'..='\u{218F}' |
21 '\u{2C00}'..='\u{2FEF}' |
22 '\u{3001}'..='\u{D7FF}' |
23 '\u{F900}'..='\u{FDCF}' |
24 '\u{FDF0}'..='\u{FFFD}' |
25 '\u{10000}'..='\u{EFFFF}')
26}
27
28pub(crate) fn is_valid_continuation(c: char) -> bool {
29 is_valid_start(c) ||
30 matches!(c,
31 '-' |
32 '.' |
33 '0'..='9' |
34 '\u{B7}' |
35 '\u{300}'..='\u{36F}' |
36 '\u{203F}'..='\u{2040}')
37}
38
39pub(crate) fn matches_name_production(name: &str) -> bool {
40 let mut iter = name.chars();
41
42 if iter.next().is_none_or(|c| !is_valid_start(c)) {
43 return false;
44 }
45 iter.all(is_valid_continuation)
46}