hawktracer_parser/
registry.rs

1use 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}