1use std::collections::HashMap;
10
11use crate::datatype::DataType;
12use crate::error::{Result, SparkplugError};
13
14#[derive(Clone, Debug, PartialEq, Eq, Hash)]
16pub enum MetricKey {
17 Name(String),
19 Alias(u64),
21}
22
23#[derive(Clone, Debug, Default)]
26pub struct AliasRegistry {
27 name_to_alias: HashMap<String, u64>,
28 alias_to_name: HashMap<u64, String>,
29 dt_by_name: HashMap<String, DataType>,
30 dt_by_alias: HashMap<u64, DataType>,
31}
32
33impl AliasRegistry {
34 #[must_use]
36 pub fn new() -> Self {
37 Self::default()
38 }
39
40 pub fn bind(&mut self, name: &str, alias: Option<u64>, datatype: DataType) {
44 self.dt_by_name.insert(name.to_owned(), datatype);
45 if let Some(alias) = alias {
46 self.name_to_alias.insert(name.to_owned(), alias);
47 self.alias_to_name.insert(alias, name.to_owned());
48 self.dt_by_alias.insert(alias, datatype);
49 }
50 }
51
52 pub fn try_bind(&mut self, name: &str, alias: Option<u64>, datatype: DataType) -> Result<()> {
59 if let Some(alias) = alias
60 && let Some(existing) = self.alias_to_name.get(&alias)
61 && existing != name
62 {
63 return Err(SparkplugError::InvalidId(format!(
64 "alias {alias} already bound to {existing:?}, cannot rebind to {name:?}"
65 )));
66 }
67 self.bind(name, alias, datatype);
68 Ok(())
69 }
70
71 #[must_use]
73 pub fn datatype_for_name(&self, name: &str) -> Option<DataType> {
74 self.dt_by_name.get(name).copied()
75 }
76
77 #[must_use]
79 pub fn datatype_for_alias(&self, alias: u64) -> Option<DataType> {
80 self.dt_by_alias.get(&alias).copied()
81 }
82
83 #[must_use]
85 pub fn datatype_for(&self, key: &MetricKey) -> Option<DataType> {
86 match key {
87 MetricKey::Name(n) => self.datatype_for_name(n),
88 MetricKey::Alias(a) => self.datatype_for_alias(*a),
89 }
90 }
91
92 #[must_use]
94 pub fn name_for_alias(&self, alias: u64) -> Option<&str> {
95 self.alias_to_name.get(&alias).map(String::as_str)
96 }
97
98 #[must_use]
100 pub fn alias_for_name(&self, name: &str) -> Option<u64> {
101 self.name_to_alias.get(name).copied()
102 }
103
104 #[must_use]
106 pub fn alias_exists(&self, alias: u64) -> bool {
107 self.alias_to_name.contains_key(&alias)
108 }
109
110 pub fn clear(&mut self) {
112 self.name_to_alias.clear();
113 self.alias_to_name.clear();
114 self.dt_by_name.clear();
115 self.dt_by_alias.clear();
116 }
117}