Skip to main content

coil_core/
registry.rs

1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct ServiceDescriptor {
5    pub id: String,
6    pub owner: ServiceOwner,
7    pub description: String,
8}
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ServiceOwner {
12    Core,
13    Module(String),
14    CustomerApp,
15}
16
17pub trait PlatformModule {
18    fn manifest(&self) -> ModuleManifest;
19    fn register(&self, registry: &mut ServiceRegistry) -> Result<(), RegistrationError>;
20    fn install_migration_plan(&self) -> Option<MigrationPlan> {
21        None
22    }
23}
24
25#[derive(Debug, Default, Clone)]
26pub struct ServiceRegistry {
27    services: HashMap<String, ServiceDescriptor>,
28    modules: HashMap<String, ModuleManifest>,
29}
30
31impl ServiceRegistry {
32    pub fn new() -> Self {
33        Self::default()
34    }
35
36    pub fn register_core_service(
37        &mut self,
38        id: impl Into<String>,
39        description: impl Into<String>,
40    ) -> Result<(), RegistrationError> {
41        self.register(ServiceDescriptor {
42            id: id.into(),
43            owner: ServiceOwner::Core,
44            description: description.into(),
45        })
46    }
47
48    pub fn register_module_service(
49        &mut self,
50        module: impl Into<String>,
51        id: impl Into<String>,
52        description: impl Into<String>,
53    ) -> Result<(), RegistrationError> {
54        self.register(ServiceDescriptor {
55            id: id.into(),
56            owner: ServiceOwner::Module(module.into()),
57            description: description.into(),
58        })
59    }
60
61    pub fn register_customer_app_service(
62        &mut self,
63        id: impl Into<String>,
64        description: impl Into<String>,
65    ) -> Result<(), RegistrationError> {
66        self.register(ServiceDescriptor {
67            id: id.into(),
68            owner: ServiceOwner::CustomerApp,
69            description: description.into(),
70        })
71    }
72
73    pub fn register_module_manifest(
74        &mut self,
75        manifest: ModuleManifest,
76    ) -> Result<(), RegistrationError> {
77        if self.modules.contains_key(&manifest.name) {
78            return Err(RegistrationError::DuplicateModule {
79                name: manifest.name.clone(),
80            });
81        }
82
83        self.modules.insert(manifest.name.clone(), manifest);
84        Ok(())
85    }
86
87    pub fn services(&self) -> impl Iterator<Item = &ServiceDescriptor> {
88        self.services.values()
89    }
90
91    pub fn modules(&self) -> impl Iterator<Item = &ModuleManifest> {
92        self.modules.values()
93    }
94
95    fn register(&mut self, service: ServiceDescriptor) -> Result<(), RegistrationError> {
96        if self.services.contains_key(&service.id) {
97            return Err(RegistrationError::DuplicateService {
98                id: service.id.clone(),
99            });
100        }
101
102        self.services.insert(service.id.clone(), service);
103        Ok(())
104    }
105}
106
107#[derive(Debug, Error, PartialEq, Eq)]
108pub enum RegistrationError {
109    #[error("service `{id}` is already registered")]
110    DuplicateService { id: String },
111    #[error("module `{name}` is already registered")]
112    DuplicateModule { name: String },
113}