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 self.local.contains_key(&descriptor.name) {
88 return Err(CapabilityError::HandlerAlreadyRegistered(
89 descriptor.name.clone(),
90 ));
91 }
92 self.local.insert(
93 descriptor.name.clone(),
94 LocalCapabilityProvider::new(descriptor, handler),
95 );
96 Ok(())
97 }
98
99 pub fn get(&self, capability: &CapabilityName) -> Option<&LocalCapabilityProvider> {
101 self.local.get(capability)
102 }
103
104 pub fn descriptors(&self) -> Vec<CapabilityDescriptor> {
106 self.local
107 .values()
108 .map(|provider| provider.descriptor.clone())
109 .collect()
110 }
111}