1use crate::event::DataType;
2use crate::event::Event;
3use crate::event_klass::EventKlass;
4use crate::registry::CoreEventKlassId;
5use crate::registry::EventKlassRegistry;
6
7pub struct RegistryUpdater<'a> {
8 registry: &'a mut EventKlassRegistry,
9}
10
11impl<'a> RegistryUpdater<'a> {
12 pub fn new(registry: &'a mut EventKlassRegistry) -> RegistryUpdater<'a> {
13 RegistryUpdater { registry }
14 }
15
16 pub fn update_registry_from_event(&mut self, event: &Event) -> Result<(), &'static str> {
17 match event.get_klass_id() {
18 x if x == CoreEventKlassId::KlassInfo as u32 => self.add_new_klass(&event),
19 x if x == CoreEventKlassId::FieldInfo as u32 => self.add_klass_field(&event),
20 _ => Err("Klass id is neither KlassInfo nor FieldInfo"),
21 }
22 }
23
24 fn add_new_klass(&mut self, event: &Event) -> Result<(), &'static str> {
25 let klass_id = match event.get_value_u32("info_klass_id") {
26 Ok(value) => value,
27 Err(_) => return Err("Cannot read klass id"),
28 };
29
30 if CoreEventKlassId::is_core_klass(klass_id) {
31 return Ok(());
32 }
33
34 let klass_name = match event.get_value_string("event_klass_name") {
35 Ok(value) => value.clone(),
36 Err(_) => return Err("Cannot read klass name"),
37 };
38
39 self.registry
40 .add_klass(EventKlass::new(klass_id, klass_name));
41 Ok(())
42 }
43
44 fn add_klass_field(&mut self, event: &Event) -> Result<(), &'static str> {
45 let klass_id = match event.get_value_u32("info_klass_id") {
46 Ok(value) => value,
47 Err(_) => return Err("Cannot read klass id"),
48 };
49
50 if CoreEventKlassId::is_core_klass(klass_id) {
51 return Ok(()); }
53
54 let field_name = match event.get_value_string("field_name") {
55 Ok(value) => value.clone(),
56 Err(_) => return Err("Cannot read field name"),
57 };
58
59 let type_name = match event.get_value_string("field_type") {
60 Ok(value) => value.clone(),
61 Err(_) => return Err("Cannot read field type"),
62 };
63
64 let data_type = match event.get_value_u8("data_type") {
65 Ok(value) => match value {
66 1 => DataType::Struct,
67 2 => DataType::Str,
68 6 => DataType::U64, 99 => {
70 if let Ok(size) = event.get_value_u64("size") {
71 match size {
72 1 => DataType::U8,
73 4 => DataType::U32,
74 8 => DataType::U64,
75 _ => return Err("Invalid size of integer type"),
76 }
77 } else {
78 return Err("Cannot read field size");
79 }
80 }
81 _ => return Err("Invalid data type"),
82 },
83 Err(_) => return Err("Cannot read field data type"),
84 };
85
86 match self.registry.get_klass_by_id_mut(klass_id) {
87 Some(klass) => {
88 klass.add_field(field_name, type_name, data_type);
89 Ok(())
90 }
91 None => Err("Cannot find klass"),
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use crate::event::Value;
100
101 fn make_klass_info_event(
102 id: Option<u32>,
103 name: Option<&str>,
104 field_count: Option<u8>,
105 ) -> Event {
106 let mut values = std::collections::HashMap::new();
107
108 if id.is_some() {
109 values.insert("info_klass_id".to_string(), Value::U32(id.unwrap()));
110 }
111 if name.is_some() {
112 values.insert(
113 "event_klass_name".to_string(),
114 Value::Str(name.unwrap().to_string()),
115 );
116 }
117 if field_count.is_some() {
118 values.insert("field_count".to_string(), Value::U8(field_count.unwrap()));
119 }
120
121 Event::new(CoreEventKlassId::KlassInfo as u32, values)
122 }
123
124 fn make_field_info_event(
125 klass_id: Option<u32>,
126 field_type: Option<&str>,
127 field_name: Option<&str>,
128 size: Option<u64>,
129 data_type: Option<u8>,
130 ) -> Event {
131 let mut values = std::collections::HashMap::new();
132
133 if klass_id.is_some() {
134 values.insert("info_klass_id".to_string(), Value::U32(klass_id.unwrap()));
135 }
136 if field_type.is_some() {
137 values.insert(
138 "field_type".to_string(),
139 Value::Str(field_type.unwrap().to_string()),
140 );
141 }
142 if field_name.is_some() {
143 values.insert(
144 "field_name".to_string(),
145 Value::Str(field_name.unwrap().to_string()),
146 );
147 }
148 if size.is_some() {
149 values.insert("size".to_string(), Value::U64(size.unwrap()));
150 }
151 if data_type.is_some() {
152 values.insert("data_type".to_string(), Value::U8(data_type.unwrap()));
153 }
154
155 Event::new(CoreEventKlassId::FieldInfo as u32, values)
156 }
157
158 #[test]
159 fn should_fail_if_event_is_not_field_or_klass_info_event() {
160 let mut registry = EventKlassRegistry::new();
161 let mut updater = RegistryUpdater::new(&mut registry);
162 let event = Event::new(99, std::collections::HashMap::new());
163
164 assert!(updater.update_registry_from_event(&event).is_err());
165 }
166
167 #[test]
168 fn should_add_new_klass_to_registry_if_all_fields_are_in_event() {
169 let mut registry = EventKlassRegistry::new();
170
171 {
172 let mut updater = RegistryUpdater::new(&mut registry);
173 assert!(updater
174 .update_registry_from_event(&make_klass_info_event(Some(99), Some("name"), Some(0)))
175 .is_ok());
176 }
177
178 assert!(registry.get_klass_by_id(99).is_some());
179 assert!(registry.get_klass_by_name("name").is_some());
180 }
181
182 #[test]
183 fn add_new_klass_to_registry_if_some_fields_are_missing_should_fail() {
184 let mut registry = EventKlassRegistry::new();
185
186 {
187 let mut updater = RegistryUpdater::new(&mut registry);
188 assert!(updater
189 .update_registry_from_event(&make_klass_info_event(None, Some("name"), Some(0)))
190 .is_err());
191 assert!(updater
192 .update_registry_from_event(&make_klass_info_event(Some(99), None, Some(0)))
193 .is_err());
194 }
195 }
196
197 #[test]
198 fn add_core_klass_to_registry_should_not_fail() {
199 let mut registry = EventKlassRegistry::new();
200
201 {
202 let mut updater = RegistryUpdater::new(&mut registry);
203 assert!(updater
204 .update_registry_from_event(&make_klass_info_event(
205 Some(CoreEventKlassId::Base as u32),
206 Some("new_name"),
207 Some(0)
208 ))
209 .is_ok());
210 }
211
212 assert_eq!(
213 *registry
214 .get_klass_by_id(CoreEventKlassId::Base as u32)
215 .unwrap()
216 .get_name(),
217 "HT_Event".to_string()
218 );
219 }
220
221 #[test]
222 fn add_field_to_non_existing_klass_should_fail() {
223 let mut registry = EventKlassRegistry::new();
224
225 {
226 let mut updater = RegistryUpdater::new(&mut registry);
227 let event = make_field_info_event(Some(99), Some("t"), Some("n"), Some(4), Some(99));
228 assert!(updater.update_registry_from_event(&event).is_err());
229 }
230 }
231
232 #[test]
233 fn add_field_if_some_values_are_missing_should_fail() {
234 let mut registry = EventKlassRegistry::new();
235 let mut updater = RegistryUpdater::new(&mut registry);
236 assert!(updater
237 .update_registry_from_event(&make_klass_info_event(Some(99), Some("name"), Some(10)))
238 .is_ok());
239
240 assert!(updater
241 .update_registry_from_event(&make_field_info_event(
242 None,
243 Some("t"),
244 Some("n"),
245 Some(4),
246 Some(1)
247 ))
248 .is_err());
249 assert!(updater
250 .update_registry_from_event(&make_field_info_event(
251 Some(99),
252 None,
253 Some("n"),
254 Some(4),
255 Some(2)
256 ))
257 .is_err());
258 assert!(updater
259 .update_registry_from_event(&make_field_info_event(
260 Some(99),
261 Some("u"),
262 None,
263 Some(4),
264 Some(6)
265 ))
266 .is_err());
267 assert!(updater
268 .update_registry_from_event(&make_field_info_event(
269 Some(99),
270 Some("v"),
271 Some("n"),
272 None,
273 Some(99)
274 ))
275 .is_err());
276 assert!(updater
277 .update_registry_from_event(&make_field_info_event(
278 Some(99),
279 Some("w"),
280 Some("n"),
281 Some(99),
282 None
283 ))
284 .is_err());
285 }
286
287 #[test]
288 fn add_field_to_core_klass_should_not_update_klass() {
289 let mut registry = EventKlassRegistry::new();
290
291 {
292 let mut updater = RegistryUpdater::new(&mut registry);
293 let event = make_field_info_event(
294 Some(CoreEventKlassId::Base as u32),
295 Some("t"),
296 Some("n"),
297 Some(4),
298 Some(99),
299 );
300 assert!(updater.update_registry_from_event(&event).is_ok());
301 }
302
303 assert_eq!(
304 registry
305 .get_klass_by_id(CoreEventKlassId::Base as u32)
306 .unwrap()
307 .get_fields()
308 .len(),
309 3
310 );
311 }
312
313 #[test]
314 fn add_uint_field_with_invalid_size_should_fail() {
315 let mut registry = EventKlassRegistry::new();
316 let mut updater = RegistryUpdater::new(&mut registry);
317 assert!(updater
318 .update_registry_from_event(&make_klass_info_event(Some(99), Some("name"), Some(10)))
319 .is_ok());
320
321 assert!(updater
322 .update_registry_from_event(&make_field_info_event(
323 Some(99),
324 Some("t"),
325 Some("n"),
326 Some(99),
327 Some(10)
328 ))
329 .is_err());
330 }
331}