Skip to main content

coil_ops/search/
catalog.rs

1use super::*;
2use coil_core::ModuleManifest;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct SearchCatalog {
6    pub contributions: Vec<SearchIndexContribution>,
7}
8
9impl SearchCatalog {
10    pub fn new(contributions: Vec<SearchIndexContribution>) -> Self {
11        Self { contributions }
12    }
13
14    pub fn standard() -> Self {
15        Self {
16            contributions: Vec::new(),
17        }
18    }
19
20    pub fn from_manifests(manifests: &[ModuleManifest]) -> Result<Self, OpsModelError> {
21        let mut contributions = Vec::new();
22        for manifest in manifests {
23            for contribution in &manifest.search_contributions {
24                contributions.push(SearchIndexContribution::from_manifest_contribution(
25                    &manifest.name,
26                    contribution,
27                )?);
28            }
29        }
30        let catalog = Self::new(contributions);
31        catalog.validate()?;
32        Ok(catalog)
33    }
34
35    pub fn validate(&self) -> Result<(), OpsModelError> {
36        let mut seen = HashSet::new();
37        for contribution in &self.contributions {
38            if !seen.insert(contribution.id.as_str().to_string()) {
39                return Err(OpsModelError::DuplicateIdentifier {
40                    kind: "search index",
41                    id: contribution.id.to_string(),
42                });
43            }
44            SearchIndexContribution::new(
45                contribution.id.clone(),
46                contribution.source_module.clone(),
47                contribution.document_kind,
48                contribution.visibility,
49                contribution.publication_required,
50                contribution.fields.clone(),
51                contribution.invalidation_rules.clone(),
52                contribution.rebuild_strategy,
53            )?;
54        }
55
56        Ok(())
57    }
58
59    pub fn contribution(&self, id: &SearchIndexId) -> Option<&SearchIndexContribution> {
60        self.contributions
61            .iter()
62            .find(|contribution| &contribution.id == id)
63    }
64
65    pub fn visible_to(&self, capabilities: &[Capability]) -> Vec<&SearchIndexContribution> {
66        self.contributions
67            .iter()
68            .filter(|contribution| contribution.visible_to(capabilities))
69            .collect()
70    }
71}
72
73impl Default for SearchCatalog {
74    fn default() -> Self {
75        Self::standard()
76    }
77}