myko/server/
handler_registry.rs1use std::sync::Arc;
7
8use crate::{
9 command::CommandHandlerRegistration,
10 item::{IngestBufferPolicy, IngestBufferRegistration, ItemParseFn, ItemRegistration},
11 query::{QueryCellFactory, QueryParseFn, QueryRegistration},
12 report::{ReportCellFactory, ReportParseFn, ReportRegistration},
13 view::{ViewCellFactory, ViewParseFn, ViewRegistration},
14};
15
16type AMap<K, V> = std::collections::HashMap<K, V, ahash::RandomState>;
20
21pub struct StoredQueryData {
23 pub query_id: Arc<str>,
24 pub query_item_type: Arc<str>,
25 pub parse: QueryParseFn,
26 pub cell_factory: QueryCellFactory,
27}
28
29pub struct StoredViewData {
31 pub view_id: Arc<str>,
32 pub view_item_type: Arc<str>,
33 pub parse: ViewParseFn,
34 pub cell_factory: ViewCellFactory,
35}
36
37pub struct StoredReportData {
39 pub report_id: Arc<str>,
40 pub parse: ReportParseFn,
41 pub cell_factory: ReportCellFactory,
42}
43
44pub struct HandlerRegistry {
49 item_parsers: AMap<Arc<str>, ItemParseFn>,
51 item_buffer_policies: AMap<Arc<str>, IngestBufferPolicy>,
53 query_data: AMap<Arc<str>, StoredQueryData>,
55 view_data: AMap<Arc<str>, StoredViewData>,
57 report_data: AMap<Arc<str>, StoredReportData>,
59}
60
61impl HandlerRegistry {
62 pub fn new() -> Self {
64 let mut item_parsers = AMap::default();
65 let mut item_buffer_policies = AMap::default();
66 let mut query_data = AMap::default();
67 let mut view_data = AMap::default();
68 let mut report_data = AMap::default();
69
70 for registration in inventory::iter::<ItemRegistration> {
72 log::trace!("Registered item parser: {}", registration.entity_type);
73 item_parsers.insert(registration.entity_type.into(), registration.parse);
74 }
75
76 for registration in inventory::iter::<IngestBufferRegistration> {
77 log::trace!(
78 "Registered ingest buffer policy: {} -> {:?}",
79 registration.entity_type,
80 registration.policy
81 );
82 item_buffer_policies.insert(registration.entity_type.into(), registration.policy);
83 }
84
85 for registration in inventory::iter::<QueryRegistration> {
87 log::trace!("Registered query: {}", registration.query_id);
88 let data = StoredQueryData {
89 query_id: registration.query_id.into(),
90 query_item_type: registration.query_item_type.into(),
91 parse: registration.parse,
92 cell_factory: registration.cell_factory,
93 };
94 query_data.insert(data.query_id.clone(), data);
95 }
96
97 for registration in inventory::iter::<ViewRegistration> {
99 log::trace!("Registered view: {}", registration.view_id);
100 let data = StoredViewData {
101 view_id: registration.view_id.into(),
102 view_item_type: registration.view_item_type.into(),
103 parse: registration.parse,
104 cell_factory: registration.cell_factory,
105 };
106 view_data.insert(data.view_id.clone(), data);
107 }
108
109 for registration in inventory::iter::<ReportRegistration> {
111 log::trace!("Registered report: {}", registration.report_id);
112 let data = StoredReportData {
113 report_id: registration.report_id.into(),
114 parse: registration.parse,
115 cell_factory: registration.cell_factory,
116 };
117 report_data.insert(data.report_id.clone(), data);
118 }
119
120 let mut command_ids: Vec<&str> = inventory::iter::<CommandHandlerRegistration>()
122 .map(|r| r.command_id)
123 .collect();
124 command_ids.sort_unstable();
125
126 fn format_list<'a>(keys: impl Iterator<Item = &'a Arc<str>>) -> String {
127 let mut items: Vec<&str> = keys.map(|k| k.as_ref()).collect();
128 items.sort_unstable();
129 if items.is_empty() {
130 "(none)".to_string()
131 } else {
132 items.join(", ")
133 }
134 }
135
136 fn format_str_list(items: &[&str]) -> String {
137 if items.is_empty() {
138 "(none)".to_string()
139 } else {
140 items.join(", ")
141 }
142 }
143
144 log::trace!(
145 "HandlerRegistry initialized:\n Items ({}):\n {}\n Queries ({}):\n {}\n Views ({}):\n {}\n Reports ({}):\n {}\n Commands ({}):\n {}",
146 item_parsers.len(),
147 format_list(item_parsers.keys()),
148 query_data.len(),
149 format_list(query_data.keys()),
150 view_data.len(),
151 format_list(view_data.keys()),
152 report_data.len(),
153 format_list(report_data.keys()),
154 command_ids.len(),
155 format_str_list(&command_ids),
156 );
157
158 Self {
159 item_parsers,
160 item_buffer_policies,
161 query_data,
162 view_data,
163 report_data,
164 }
165 }
166
167 pub fn get_item_parser(&self, entity_type: &str) -> Option<ItemParseFn> {
169 self.item_parsers.get(entity_type).copied()
170 }
171
172 pub fn get_item_buffer_policy(&self, entity_type: &str) -> IngestBufferPolicy {
174 self.item_buffer_policies
175 .get(entity_type)
176 .copied()
177 .unwrap_or(IngestBufferPolicy::None)
178 }
179
180 pub fn get_query(&self, query_id: &str) -> Option<&StoredQueryData> {
182 self.query_data.get(query_id)
183 }
184
185 pub fn get_report(&self, report_id: &str) -> Option<&StoredReportData> {
187 self.report_data.get(report_id)
188 }
189
190 pub fn get_view(&self, view_id: &str) -> Option<&StoredViewData> {
192 self.view_data.get(view_id)
193 }
194
195 pub fn has_item_parser(&self, entity_type: &str) -> bool {
197 self.item_parsers.contains_key(entity_type)
198 }
199
200 pub fn entity_types(&self) -> impl Iterator<Item = &Arc<str>> {
202 self.item_parsers.keys()
203 }
204
205 pub fn query_ids(&self) -> impl Iterator<Item = &Arc<str>> {
207 self.query_data.keys()
208 }
209
210 pub fn report_ids(&self) -> impl Iterator<Item = &Arc<str>> {
212 self.report_data.keys()
213 }
214
215 pub fn view_ids(&self) -> impl Iterator<Item = &Arc<str>> {
217 self.view_data.keys()
218 }
219}
220
221impl Default for HandlerRegistry {
222 fn default() -> Self {
223 Self::new()
224 }
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230
231 #[test]
232 fn test_registry_creation() {
233 let registry = HandlerRegistry::new();
235 let _ = registry.entity_types().count();
237 }
238}