1use std::collections::HashMap;
7
8use smpte_types::Auid;
9
10use crate::DictError;
11
12pub struct LabelsRegister {
14 map: HashMap<Auid, String>,
15}
16
17impl LabelsRegister {
18 pub fn from_xml(xml: &[u8]) -> Result<Self, DictError> {
24 let text = std::str::from_utf8(xml).map_err(|e| DictError::Xml(e.to_string()))?;
25 let doc = roxmltree::Document::parse(text).map_err(|e| DictError::Xml(e.to_string()))?;
26 let root = doc.root_element();
27 if root.tag_name().name() != "LabelsRegister" {
28 return Ok(Self {
29 map: HashMap::new(),
30 });
31 }
32
33 let mut map = HashMap::new();
34
35 let entries = match root.children().find(|n| n.tag_name().name() == "Entries") {
36 Some(e) => e,
37 None => return Ok(Self { map }),
38 };
39
40 for entry in entries
41 .children()
42 .filter(|n| n.tag_name().name() == "Entry")
43 {
44 let kind = entry
46 .children()
47 .find(|n| n.tag_name().name() == "Kind")
48 .and_then(|n| n.text());
49 if kind == Some("NODE") {
50 continue;
51 }
52
53 let ul_str = match entry
54 .children()
55 .find(|n| n.tag_name().name() == "UL")
56 .and_then(|n| n.text())
57 {
58 Some(s) => s,
59 None => continue,
60 };
61
62 let symbol = match entry
63 .children()
64 .find(|n| n.tag_name().name() == "Symbol")
65 .and_then(|n| n.text())
66 {
67 Some(s) => s,
68 None => continue,
69 };
70
71 if let Ok(auid) = Auid::from_urn(ul_str) {
72 map.insert(auid, symbol.to_owned());
73 }
74 }
75
76 Ok(Self { map })
77 }
78
79 pub fn empty() -> Self {
81 Self {
82 map: HashMap::new(),
83 }
84 }
85
86 pub fn get(&self, id: &Auid) -> Option<&str> {
88 self.map.get(id).map(String::as_str)
89 }
90
91 pub fn merge(mut self, other: Self) -> Self {
93 for (k, v) in other.map {
94 self.map.entry(k).or_insert(v);
95 }
96 self
97 }
98
99 pub fn len(&self) -> usize {
101 self.map.len()
102 }
103
104 pub fn is_empty(&self) -> bool {
106 self.map.is_empty()
107 }
108}