script/dom/bindings/
xmlname.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Functions for validating and extracting qualified XML names.
6
7/// Check if an element name is valid. See <http://www.w3.org/TR/xml/#NT-Name>
8/// for details.
9pub(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}