1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use super::mathml;
use super::xml;
use std::collections::HashMap;
#[derive(Debug, PartialEq, Eq)]
pub struct Namespace {
pub prefix: &'static str,
pub uri: &'static str,
}
const XMLNS_NAMESPACE_PREFIX: &str = "xmlns";
const XMLNS_NAMESPACE: Namespace = Namespace {
prefix: XMLNS_NAMESPACE_PREFIX,
uri: "http://www.w3.org/2000/xmlns/",
};
const XHTML_NAMESPACE_PREFIX: &str = "xhtml";
const XHTML_NAMESPACE: Namespace = Namespace {
prefix: XHTML_NAMESPACE_PREFIX,
uri: "http://www.w3.org/1999/xhtml",
};
const SVG_NAMESPACE_PREFIX: &str = "svg";
const SVG_NAMESPACE: Namespace = Namespace {
prefix: SVG_NAMESPACE_PREFIX,
uri: "http://www.w3.org/2000/svg",
};
const U_NAMESPACE_PREFIX: &str = "u";
const U_NAMESPACE: Namespace = Namespace {
prefix: U_NAMESPACE_PREFIX,
uri: "http://danieljrmay.com/U",
};
pub struct NamespaceRegistry {
custom_namespaces: HashMap<&'static str, Namespace>,
}
impl NamespaceRegistry {
pub fn new() -> NamespaceRegistry {
NamespaceRegistry {
custom_namespaces: HashMap::new(),
}
}
pub fn get(&self, prefix: &str) -> Option<&Namespace> {
match prefix.as_ref() {
XMLNS_NAMESPACE_PREFIX => Some(&XMLNS_NAMESPACE),
xml::NAMESPACE_PREFIX => Some(&xml::NAMESPACE),
XHTML_NAMESPACE_PREFIX => Some(&XHTML_NAMESPACE),
mathml::NAMESPACE_PREFIX => Some(&mathml::NAMESPACE),
SVG_NAMESPACE_PREFIX => Some(&SVG_NAMESPACE),
U_NAMESPACE_PREFIX => Some(&U_NAMESPACE),
_ => self.custom_namespaces.get(prefix),
}
}
pub fn add(&mut self, prefix: &'static str, uri: &'static str) {
if self.custom_namespaces.contains_key(prefix) {
panic!("Namespace prefix already exists.");
}
for v in self.custom_namespaces.values() {
if v.uri == uri {
panic!("Namespace uri already exists.");
}
}
let namespace = Namespace {
prefix: prefix,
uri: uri,
};
self.custom_namespaces.insert(prefix, namespace);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn predefined_namspaces() {
let nsr: NamespaceRegistry = NamespaceRegistry::new();
let xml_ns = nsr.get("xml").unwrap();
assert_eq!(xml_ns.prefix, "xml");
assert_eq!(xml_ns.uri, "http://www.w3.org/XML/1998/namespace");
let xhtml_ns = nsr.get("xhtml").unwrap();
assert_eq!(xhtml_ns.prefix, "xhtml");
assert_eq!(xhtml_ns.uri, "http://www.w3.org/1999/xhtml");
let mathml_ns = nsr.get("mathml").unwrap();
assert_eq!(mathml_ns.prefix, "mathml");
assert_eq!(mathml_ns.uri, "http://www.w3.org/1998/Math/MathML");
let svg_ns = nsr.get("svg").unwrap();
assert_eq!(svg_ns.prefix, "svg");
assert_eq!(svg_ns.uri, "http://www.w3.org/2000/svg");
let u_ns = nsr.get("u").unwrap();
assert_eq!(u_ns.prefix, "u");
assert_eq!(u_ns.uri, "http://danieljrmay.com/U");
}
}