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}