1 | use super::*; |
2 | |
3 | #[derive (Debug)] |
4 | pub struct Tree { |
5 | pub namespace: &'static str, |
6 | pub nested: std::collections::BTreeMap<&'static str, Tree>, |
7 | } |
8 | |
9 | impl Tree { |
10 | pub fn new(reader: &'static metadata::Reader) -> Self { |
11 | let mut tree = Tree::from_namespace("" ); |
12 | for ns in reader.namespaces() { |
13 | if reader.includes_namespace(ns) { |
14 | tree.insert_namespace(ns, 0); |
15 | } |
16 | } |
17 | tree |
18 | } |
19 | |
20 | fn from_namespace(namespace: &'static str) -> Self { |
21 | Self { namespace, nested: std::collections::BTreeMap::new() } |
22 | } |
23 | fn insert_namespace(&mut self, namespace: &'static str, pos: usize) -> &mut Self { |
24 | if let Some(next) = namespace[pos..].find('.' ) { |
25 | let next = pos + next; |
26 | self.nested.entry(&namespace[pos..next]).or_insert_with(|| Self::from_namespace(&namespace[..next])).insert_namespace(namespace, next + 1) |
27 | } else { |
28 | self.nested.entry(&namespace[pos..]).or_insert_with(|| Self::from_namespace(namespace)) |
29 | } |
30 | } |
31 | pub fn flatten(&self) -> Vec<&Self> { |
32 | let mut flatten = if self.namespace.is_empty() { vec![] } else { vec![self] }; |
33 | flatten.extend(self.nested.values().flat_map(|tree| tree.flatten())); |
34 | flatten |
35 | } |
36 | } |
37 | |