appcore_capabilities/
registry.rs1use crate::{
12 CapabilityError, CapabilityRequest, CapabilityResponse, CapabilityResult,
13 LocalCapabilityHandler,
14};
15use appcore_core::{CapabilityDescriptor, CapabilityName};
16use std::collections::HashMap;
17use std::sync::Arc;
18
19#[derive(Clone)]
21pub struct LocalCapabilityProvider {
22 descriptor: CapabilityDescriptor,
23 handler: Arc<dyn LocalCapabilityHandler>,
24}
25
26impl std::fmt::Debug for LocalCapabilityProvider {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 f.debug_struct("LocalCapabilityProvider")
29 .field("descriptor", &self.descriptor)
30 .finish_non_exhaustive()
31 }
32}
33
34impl LocalCapabilityProvider {
35 pub(crate) fn new(
36 descriptor: CapabilityDescriptor,
37 handler: Arc<dyn LocalCapabilityHandler>,
38 ) -> Self {
39 Self {
40 descriptor,
41 handler,
42 }
43 }
44
45 pub fn descriptor(&self) -> &CapabilityDescriptor {
47 &self.descriptor
48 }
49
50 pub fn is_healthy(&self) -> bool {
52 self.handler.is_healthy()
53 }
54
55 pub fn handle(&self, request: &CapabilityRequest) -> CapabilityResult<CapabilityResponse> {
57 self.handler.handle(request)
58 }
59}
60
61#[derive(Debug, Clone, Default)]
63pub struct CapabilityRegistry {
64 local: HashMap<CapabilityName, LocalCapabilityProvider>,
65}
66
67impl CapabilityRegistry {
68 pub fn new() -> Self {
70 Self::default()
71 }
72
73 pub fn register_handler<H>(&mut self, handler: H) -> CapabilityResult<()>
75 where
76 H: LocalCapabilityHandler + 'static,
77 {
78 self.register_shared_handler(Arc::new(handler))
79 }
80
81 pub fn register_shared_handler(
83 &mut self,
84 handler: Arc<dyn LocalCapabilityHandler>,
85 ) -> CapabilityResult<()> {
86 let descriptor = handler.descriptor();
87 if descriptor.version.is_empty() || descriptor.version.len() > 256 {
88 return Err(CapabilityError::HandlerRejected(
89 "invalid_descriptor_version_length".into(),
90 ));
91 }
92 if self.local.contains_key(&descriptor.name) {
93 return Err(CapabilityError::HandlerAlreadyRegistered(
94 descriptor.name.clone(),
95 ));
96 }
97 if self.local.len() >= 4096 {
98 return Err(CapabilityError::HandlerRejected(
99 "local_registry_capacity_exceeded".into(),
100 ));
101 }
102 self.local.insert(
103 descriptor.name.clone(),
104 LocalCapabilityProvider::new(descriptor, handler),
105 );
106 Ok(())
107 }
108
109 pub fn get(&self, capability: &CapabilityName) -> Option<&LocalCapabilityProvider> {
111 self.local.get(capability)
112 }
113
114 pub fn descriptors(&self) -> Vec<CapabilityDescriptor> {
117 self.local
118 .values()
119 .map(|provider| provider.descriptor.clone())
120 .collect()
121 }
122
123 pub fn iter_descriptors(&self) -> impl ExactSizeIterator<Item = &CapabilityDescriptor> {
126 self.local.values().map(LocalCapabilityProvider::descriptor)
127 }
128}