hawktracer_parser/
registry.rs1use crate::event::DataType;
2use crate::event_klass::EventKlass;
3
4#[derive(Copy, Clone)]
5pub enum CoreEventKlassId {
6 Endianness = 0,
7 Base = 1,
8 KlassInfo = 2,
9 FieldInfo = 3,
10}
11
12impl CoreEventKlassId {
13 pub fn is_core_klass(klass_id: u32) -> bool {
14 use self::CoreEventKlassId::*;
15 for val in &[Base, Endianness, FieldInfo, KlassInfo] {
16 if *val as u32 == klass_id {
17 return true;
18 }
19 }
20 false
21 }
22}
23
24#[derive(Default)]
25pub struct EventKlassRegistry {
26 klasses: std::collections::HashMap<u32, EventKlass>,
27}
28
29impl EventKlassRegistry {
30 pub fn new() -> EventKlassRegistry {
31 let mut reg = EventKlassRegistry {
32 klasses: std::collections::HashMap::new(),
33 };
34 reg.create_core_klasses();
35 reg
36 }
37
38 fn create_core_klass(
39 &mut self,
40 klass_id: CoreEventKlassId,
41 klass_name: &str,
42 fields: &[(&str, &str, DataType)],
43 ) {
44 let mut klass = EventKlass::new(klass_id as u32, klass_name.to_string());
45 for (name, type_name, data_type) in fields {
46 klass.add_field(name.to_string(), type_name.to_string(), *data_type);
47 }
48 self.klasses.insert(klass.get_id(), klass);
49 }
50
51 fn create_core_klasses(&mut self) {
52 self.create_core_klass(
53 CoreEventKlassId::Base,
54 "HT_Event",
55 &[
56 ("type", "uint32_t", DataType::U32),
57 ("timestamp", "uint64_t", DataType::U64),
58 ("id", "uint64_t", DataType::U64),
59 ],
60 );
61
62 self.create_core_klass(
63 CoreEventKlassId::Endianness,
64 "HT_EndiannessInfoEvent",
65 &[("endianness", "uint8_t", DataType::U8)],
66 );
67
68 self.create_core_klass(
69 CoreEventKlassId::KlassInfo,
70 "HT_EventKlassInfoEvent",
71 &[
72 ("info_klass_id", "uint32_t", DataType::U32),
73 ("event_klass_name", "const char*", DataType::Str),
74 ("field_count", "uint8_t", DataType::U8),
75 ],
76 );
77
78 self.create_core_klass(
79 CoreEventKlassId::FieldInfo,
80 "HT_EventKlassFieldInfoEvent",
81 &[
82 ("info_klass_id", "uint32_t", DataType::U32),
83 ("field_type", "const char*", DataType::Str),
84 ("field_name", "const char*", DataType::Str),
85 ("size", "uint64_t", DataType::U64),
86 ("data_type", "uint8_t", DataType::U8),
87 ],
88 );
89 }
90
91 pub fn add_klass(&mut self, klass: EventKlass) {
92 self.klasses.entry(klass.get_id()).or_insert(klass);
93 }
94
95 pub fn get_klass_by_id(&self, id: u32) -> Option<&EventKlass> {
96 self.klasses.get(&id)
97 }
98
99 pub fn get_klass_by_id_mut(&mut self, id: u32) -> Option<&mut EventKlass> {
100 self.klasses.get_mut(&id)
101 }
102
103 pub fn get_klass_by_name(&self, name: &str) -> Option<&EventKlass> {
104 for (_, klass) in self.klasses.iter() {
105 if klass.get_name() == name {
106 return Some(klass);
107 }
108 }
109 None
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 #[test]
117 fn get_klass_by_name_should_not_be_none_for_existing_klass() {
118 let name = String::from("test_name");
119 let mut registry = EventKlassRegistry::new();
120 registry.add_klass(EventKlass::new(99, name.clone()));
121
122 assert!(registry.get_klass_by_name(&name).is_some());
123 }
124
125 #[test]
126 fn get_klass_by_id_should_not_be_none_for_existing_klass() {
127 let klass_id = 99;
128 let mut registry = EventKlassRegistry::new();
129 registry.add_klass(EventKlass::new(klass_id, String::from("test_name")));
130
131 assert!(registry.get_klass_by_id(klass_id).is_some());
132 assert!(registry.get_klass_by_id_mut(klass_id).is_some());
133 }
134
135 #[test]
136 fn get_klass_by_name_should_be_none_if_not_exists() {
137 let registry = EventKlassRegistry::new();
138
139 assert!(registry.get_klass_by_name("test").is_none());
140 }
141
142 #[test]
143 fn check_core_event_klasses() {
144 for i in 1..4 {
145 assert!(CoreEventKlassId::is_core_klass(i));
146 }
147 assert!(!CoreEventKlassId::is_core_klass(5));
148 assert!(!CoreEventKlassId::is_core_klass(99));
149 }
150}