xrust/parser/xml/
qname.rs

1use crate::item::Node;
2use crate::parser::combinators::alt::alt2;
3use crate::parser::combinators::many::many1;
4use crate::parser::combinators::map::map;
5use crate::parser::combinators::opt::opt;
6use crate::parser::combinators::pair::pair;
7use crate::parser::combinators::support::none_of;
8use crate::parser::combinators::tag::tag;
9use crate::parser::combinators::take::{take_one, take_while};
10use crate::parser::combinators::tuple::{tuple2, tuple3};
11//use crate::parser::combinators::debug::inspect;
12use crate::parser::combinators::wellformed::wellformed;
13use crate::parser::common::{is_namechar, is_namestartchar, is_ncnamechar, is_ncnamestartchar};
14use crate::parser::xml::dtd::pereference::petextreference;
15use crate::parser::{ParseError, ParseInput};
16use crate::qname::QualifiedName;
17
18// QualifiedName
19pub(crate) fn qualname<N: Node>(
20) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, QualifiedName), ParseError> {
21    alt2(prefixed_name(), unprefixed_name())
22}
23
24// Expanded Qualified Name
25// EQName ::= QName | URIQualifiedName
26pub(crate) fn eqname<N: Node>(
27) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, QualifiedName), ParseError> {
28    alt2(uriqualname(), qualname())
29}
30// URIQualifiedName ::= "Q" "{" [^{}]* "}" NCName
31pub(crate) fn uriqualname<N: Node>(
32) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, QualifiedName), ParseError> {
33    map(
34        pair(
35            tuple3(
36                tag("Q{"),
37                map(many1(none_of("{}")), |v| v.iter().collect()),
38                tag("}"),
39            ),
40            ncname(),
41        ),
42        |((_, uri, _), localpart)| QualifiedName::new(Some(uri), None, localpart),
43    )
44}
45
46fn unprefixed_name<N: Node>(
47) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, QualifiedName), ParseError> {
48    map(alt2(petextreference(), ncname()), |localpart| {
49        QualifiedName::new(None, None, localpart)
50    })
51}
52fn prefixed_name<N: Node>(
53) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, QualifiedName), ParseError> {
54    map(
55        tuple3(
56            alt2(petextreference(), ncname()),
57            tag(":"),
58            alt2(petextreference(), ncname()),
59        ),
60        |(prefix, _, localpart)| QualifiedName::new(None, Some(prefix), localpart),
61    )
62}
63
64// NCName ::= Name - (Char* ':' Char*)
65// Name ::= NameStartChar NameChar*
66// NameStartChar ::= ':' | [A-Z] | '_' | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
67// NameChar ::= NameStartChar | '-' | '.' | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
68pub(crate) fn ncname<N: Node>(
69) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, String), ParseError> {
70    map(
71        tuple2(
72            wellformed(take_one(), is_ncnamestartchar),
73            opt(take_while(|c| is_ncnamechar(&c))),
74        ),
75        |(a, b)| [a.to_string(), b.unwrap_or_default()].concat(),
76    )
77}
78
79pub(crate) fn name<N: Node>(
80) -> impl Fn(ParseInput<N>) -> Result<(ParseInput<N>, String), ParseError> {
81    map(
82        tuple2(
83            wellformed(take_one(), is_namestartchar),
84            opt(take_while(|c| is_namechar(&c))),
85        ),
86        |(nsc, nc)| match nc {
87            None => nsc.to_string(),
88            Some(nc) => [nsc.to_string(), nc].concat(),
89        },
90    )
91}