systemprompt_extension/registry/
mod.rs1mod discovery;
2mod queries;
3mod validation;
4
5use crate::Extension;
6use crate::error::LoaderError;
7use std::collections::HashMap;
8use std::sync::Arc;
9
10pub use validation::RESERVED_PATHS;
11
12#[derive(Default)]
13pub struct ExtensionRegistry {
14 pub(crate) extensions: HashMap<String, Arc<dyn Extension>>,
15 pub(crate) sorted_extensions: Vec<Arc<dyn Extension>>,
16}
17
18impl std::fmt::Debug for ExtensionRegistry {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 f.debug_struct("ExtensionRegistry")
21 .field("extension_count", &self.extensions.len())
22 .finish_non_exhaustive()
23 }
24}
25
26impl ExtensionRegistry {
27 #[must_use]
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub(crate) fn sort_by_priority(&mut self) {
33 self.sorted_extensions.sort_by_key(|e| e.priority());
34 }
35
36 pub fn register(&mut self, ext: Arc<dyn Extension>) -> Result<(), LoaderError> {
37 let id = ext.id().to_string();
38 if self.extensions.contains_key(&id) {
39 return Err(LoaderError::DuplicateExtension(id));
40 }
41 self.extensions.insert(id, Arc::clone(&ext));
42 self.sorted_extensions.push(ext);
43 self.sort_by_priority();
44 Ok(())
45 }
46
47 pub fn merge(&mut self, extensions: Vec<Arc<dyn Extension>>) -> Result<(), LoaderError> {
48 for ext in extensions {
49 self.register(ext)?;
50 }
51 Ok(())
52 }
53
54 pub fn validate(&self) -> Result<(), LoaderError> {
55 self.validate_dependencies()?;
56 Ok(())
57 }
58
59 #[must_use]
60 pub fn len(&self) -> usize {
61 self.extensions.len()
62 }
63
64 #[must_use]
65 pub fn is_empty(&self) -> bool {
66 self.extensions.is_empty()
67 }
68}
69
70#[derive(Debug, Clone, Copy)]
71pub struct ExtensionRegistration {
72 pub factory: fn() -> Arc<dyn Extension>,
73}
74
75inventory::collect!(ExtensionRegistration);