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