ito_core/
backend_module_repository.rs1use ito_common::id::parse_module_id as parse_common_module_id;
8use ito_domain::backend::BackendModuleReader;
9use ito_domain::errors::{DomainError, DomainResult};
10use ito_domain::modules::{
11 Module, ModuleRepository as DomainModuleRepository, ModuleSummary, SubModule, SubModuleSummary,
12};
13
14pub struct BackendModuleRepository<R: BackendModuleReader> {
19 reader: R,
20}
21
22impl<R: BackendModuleReader> BackendModuleRepository<R> {
23 pub fn new(reader: R) -> Self {
25 Self { reader }
26 }
27}
28
29impl<R: BackendModuleReader> DomainModuleRepository for BackendModuleRepository<R> {
30 fn exists(&self, id: &str) -> bool {
31 let module_id = resolve_backend_module_key(id);
32 match self.reader.get_module(&module_id) {
33 Ok(_) => true,
34 Err(DomainError::NotFound { .. }) => false,
35 Err(err) => {
36 tracing::warn!("backend module exists check failed: {err}");
37 true
38 }
39 }
40 }
41
42 fn get(&self, id_or_name: &str) -> DomainResult<Module> {
43 let module_id = resolve_backend_module_key(id_or_name);
44 match self.reader.get_module(&module_id) {
45 Ok(module) => Ok(module),
46 Err(DomainError::NotFound { .. }) => Err(DomainError::not_found("module", id_or_name)),
47 Err(err) => Err(err),
48 }
49 }
50
51 fn list(&self) -> DomainResult<Vec<ModuleSummary>> {
52 let mut modules = self.reader.list_modules()?;
53 modules.sort_by(|a, b| a.id.cmp(&b.id));
54 Ok(modules)
55 }
56
57 fn list_sub_modules(&self, parent_id: &str) -> DomainResult<Vec<SubModuleSummary>> {
58 let module_id = resolve_backend_module_key(parent_id);
59 let module = match self.reader.get_module(&module_id) {
60 Ok(m) => m,
61 Err(DomainError::NotFound { .. }) => {
62 return Err(DomainError::not_found("module", parent_id));
63 }
64 Err(err) => return Err(err),
65 };
66 let mut sub_modules = Vec::with_capacity(module.sub_modules.len());
67 for s in module.sub_modules {
68 sub_modules.push(SubModuleSummary {
69 id: s.id,
70 name: s.name,
71 change_count: s.change_count,
72 });
73 }
74 sub_modules.sort_by(|a, b| a.id.cmp(&b.id));
75 Ok(sub_modules)
76 }
77
78 fn get_sub_module(&self, composite_id: &str) -> DomainResult<SubModule> {
79 let parent_id = composite_id.split('.').next().unwrap_or(composite_id);
81 let module_id = resolve_backend_module_key(parent_id);
82 let module = match self.reader.get_module(&module_id) {
83 Ok(m) => m,
84 Err(DomainError::NotFound { .. }) => {
85 return Err(DomainError::not_found("sub-module", composite_id));
86 }
87 Err(err) => return Err(err),
88 };
89 for sub in module.sub_modules {
90 if sub.id == composite_id {
91 return Ok(sub);
92 }
93 }
94 Err(DomainError::not_found("sub-module", composite_id))
95 }
96}
97
98fn resolve_backend_module_key(id_or_name: &str) -> String {
99 if let Ok(parsed) = parse_common_module_id(id_or_name) {
100 return parsed.module_id.as_str().to_string();
101 }
102
103 id_or_name.to_string()
104}