hml_rs/names/
namespace.rs

1/*a Imports
2*/
3use super::{NSMap, NSNameId, NSPrefixId, NSUriId};
4use std::collections::HashSet;
5
6//a Namespace
7//tp Namespace
8/// [Namespace] is a set of namespace prefixes and URIs, and mappings
9/// between them, that have been encountered or are defaults.
10///
11/// It also contains a stack of active mappings
12///
13/// More complex implementations will move to using BTree for the prefixes
14pub struct Namespace {
15    xmlns: bool,
16    /// ALl the
17    prefixes: Vec<String>,
18    uris: Vec<String>,
19    names: Vec<String>,
20    mappings: HashSet<NSMap>,
21}
22
23//ip Namespace
24impl Namespace {
25    //fp new
26    /// Create a new Namespace object
27    pub fn new(xmlns: bool) -> Self {
28        let uris = Vec::new();
29        let prefixes = Vec::new();
30        let names = Vec::new();
31        let mappings = HashSet::new();
32        Self {
33            xmlns,
34            uris,
35            prefixes,
36            names,
37            mappings,
38        }
39    }
40
41    //mp uses_xmlns
42    /// Returns true if the [Namespace] was constructed indicating it
43    /// should provide the standard XMLNS
44    pub fn uses_xmlns(&self) -> bool {
45        self.xmlns
46    }
47
48    //mp find_name
49    /// Find a name within the [Namespace]; return a None if not
50    /// found, or Some(NSNameId) if it is. An empty name *is* an
51    /// NSNameId::None
52    pub fn find_name(&mut self, name: &str) -> Option<NSNameId> {
53        if name.is_empty() {
54            Some(NSNameId::none())
55        } else {
56            for (i, p) in self.names.iter().enumerate() {
57                if *p == *name {
58                    return Some(NSNameId::new(i));
59                }
60            }
61            None
62        }
63    }
64
65    //mp find_prefix
66    /// Find a prefix within the [Namespace]; return a None if not
67    /// found, or Some(NSPrefixId) if it is. An empty name *is* an
68    /// NSPrefixId::None
69    pub fn find_prefix(&mut self, prefix: &str) -> Option<NSPrefixId> {
70        if prefix.is_empty() {
71            Some(NSPrefixId::none())
72        } else {
73            for (i, p) in self.prefixes.iter().enumerate() {
74                if *p == *prefix {
75                    return Some(NSPrefixId::new(i));
76                }
77            }
78            None
79        }
80    }
81
82    //mp find_uri
83    /// Find a URI within the [Namespace]; return a None if not
84    /// found, or Some(NSUriId) if it is. An empty name *is* an
85    /// NSUriId::None
86    pub fn find_uri(&mut self, uri: &str) -> Option<NSUriId> {
87        if uri.is_empty() {
88            Some(NSUriId::none())
89        } else {
90            for (i, p) in self.uris.iter().enumerate() {
91                if *p == *uri {
92                    return Some(NSUriId::new(i));
93                }
94            }
95            None
96        }
97    }
98
99    //mp find_or_add_name
100    /// Find a name within the Namespace; if it is not found then add it
101    pub(crate) fn find_or_add_name(&mut self, name: &str) -> NSNameId {
102        if let Some(id) = self.find_name(name) {
103            id
104        } else {
105            let n = self.names.len();
106            self.names.push(name.into());
107            NSNameId::new(n)
108        }
109    }
110
111    //mp find_or_add_prefix
112    /// Find a prefix within the Namespace; if it is not found then add it
113    pub(crate) fn find_or_add_prefix(&mut self, prefix: &str) -> NSPrefixId {
114        if let Some(id) = self.find_prefix(prefix) {
115            id
116        } else {
117            let n = self.prefixes.len();
118            self.prefixes.push(prefix.into());
119            NSPrefixId::new(n)
120        }
121    }
122
123    //mp find_or_add_uri
124    /// Find a URI within the Namespace; if it is not found then add it
125    fn find_or_add_uri(&mut self, uri: &str) -> NSUriId {
126        if let Some(id) = self.find_uri(uri) {
127            id
128        } else {
129            let n = self.uris.len();
130            self.uris.push(uri.into());
131            NSUriId::new(n)
132        }
133    }
134
135    //ap name_str
136    /// Borrow the `str` of a [NSNameId] within the [Namespace]
137    pub fn name_str<'a>(&'a self, name: NSNameId, default: &'a str) -> &'a str {
138        if name.is_none() {
139            default
140        } else {
141            &self.names[name.get().unwrap()]
142        }
143    }
144
145    //mp prefix_str
146    /// Borrow the `str` of a [NSPrefixId] within the [Namespace]
147    pub fn prefix_str<'a>(&'a self, prefix: NSPrefixId, default: &'a str) -> &'a str {
148        if prefix.is_none() {
149            default
150        } else {
151            &self.prefixes[prefix.get().unwrap()]
152        }
153    }
154
155    //mp uri_str
156    /// Borrow the `str` of a [NSUriId] within the [Namespace]
157    pub fn uri_str<'a>(&'a self, uri: NSUriId, default: &'a str) -> &'a str {
158        if uri.is_none() {
159            default
160        } else {
161            &self.uris[uri.get().unwrap()]
162        }
163    }
164
165    //mp add_mapping
166    /// Add a mapping from a prefix to a URI
167    pub fn add_mapping(&mut self, prefix: &str, uri: &str) -> NSMap {
168        let p_id = self.find_or_add_prefix(prefix);
169        let u_id = self.find_or_add_uri(uri);
170        self.add_mapping_by_id(p_id, u_id)
171    }
172
173    //mp add_mapping_by_id
174    /// Add a mapping from a prefix to a URI
175    pub fn add_mapping_by_id(&mut self, prefix_id: NSPrefixId, uri_id: NSUriId) -> NSMap {
176        let ns_map = NSMap::new(prefix_id, uri_id);
177        if !self.mappings.contains(&ns_map) {
178            self.mappings.insert(ns_map);
179        }
180        ns_map
181    }
182
183    //zz All done
184}
185
186//a Test
187#[cfg(test)]
188mod test {}