xee_name/
namespaces.rs

1use ahash::{HashMap, HashMapExt};
2
3pub const FN_NAMESPACE: &str = "http://www.w3.org/2005/xpath-functions";
4pub const XS_NAMESPACE: &str = "http://www.w3.org/2001/XMLSchema";
5const XML_NAMESPACE: &str = "http://www.w3.org/XML/1998/namespace";
6
7const STATIC_NAMESPACES: [(&str, &str); 7] = [
8    ("xs", XS_NAMESPACE),
9    ("fn", FN_NAMESPACE),
10    ("math", "http://www.w3.org/2005/xpath-functions/math"),
11    ("map", "http://www.w3.org/2005/xpath-functions/map"),
12    ("array", "http://www.w3.org/2005/xpath-functions/array"),
13    ("err", "http://www.w3.org/2005/xqt-errors"),
14    ("output", "http://www.w3.org/2010/xslt-xquery-serialization"),
15];
16
17#[derive(Debug, Clone)]
18pub struct Namespaces {
19    namespaces: HashMap<String, String>,
20    pub default_element_namespace: String,
21    pub default_function_namespace: String,
22}
23
24impl Namespaces {
25    pub const FN_NAMESPACE: &'static str = FN_NAMESPACE;
26
27    pub fn new(
28        namespaces: HashMap<String, String>,
29        default_element_namespace: String,
30        default_function_namespace: String,
31    ) -> Self {
32        Self {
33            namespaces,
34            default_element_namespace,
35            default_function_namespace,
36        }
37    }
38
39    pub fn default_namespaces() -> HashMap<String, String> {
40        let mut namespaces = HashMap::new();
41        namespaces.insert("xml".to_string(), XML_NAMESPACE.to_string());
42        for (prefix, uri) in STATIC_NAMESPACES.into_iter() {
43            namespaces.insert(prefix.to_string(), uri.to_string());
44        }
45        namespaces
46    }
47
48    pub fn add(&mut self, namespace_pairs: &[(&str, &str)]) {
49        for (prefix, namespace) in namespace_pairs {
50            if prefix.is_empty() {
51                self.default_element_namespace = namespace.to_string();
52            } else {
53                self.namespaces
54                    .insert(prefix.to_string(), namespace.to_string());
55            }
56        }
57    }
58
59    #[inline]
60    pub fn by_prefix(&self, prefix: &str) -> Option<&str> {
61        self.namespaces.get(prefix).map(String::as_str)
62    }
63
64    #[inline]
65    pub fn default_element_namespace(&self) -> &str {
66        self.default_element_namespace.as_str()
67    }
68}
69
70impl Default for Namespaces {
71    fn default() -> Self {
72        Self::new(
73            Self::default_namespaces(),
74            "".to_string(),
75            FN_NAMESPACE.to_string(),
76        )
77    }
78}
79
80pub trait NamespaceLookup {
81    fn by_prefix(&self, prefix: &str) -> Option<&str>;
82}
83
84impl NamespaceLookup for Namespaces {
85    fn by_prefix(&self, prefix: &str) -> Option<&str> {
86        self.namespaces.get(prefix).map(String::as_str)
87    }
88}
89
90impl<T: NamespaceLookup> NamespaceLookup for &T {
91    fn by_prefix(&self, prefix: &str) -> Option<&str> {
92        (**self).by_prefix(prefix)
93    }
94}