Skip to main content

coil_core/bootstrap/
services.rs

1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct CacheRuntimeServices {
5    pub topology: CacheTopology,
6    pub planner: CachePlanner,
7}
8
9impl CacheRuntimeServices {
10    pub fn shared_invalidation_enabled(&self) -> bool {
11        self.topology.supports_shared_invalidation()
12    }
13
14    pub fn distributed_backend(&self) -> Option<DistributedCacheBackend> {
15        self.topology.l2()
16    }
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct WasmRuntimeServices {
21    pub extension_directory: String,
22    pub allow_network: bool,
23    pub limits: WasmLimitsProfile,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct WasmLimitsProfile {
28    pub page: ResourceLimits,
29    pub api: ResourceLimits,
30    pub job: ResourceLimits,
31    pub scheduled_job: ResourceLimits,
32    pub webhook: ResourceLimits,
33    pub admin_widget: ResourceLimits,
34    pub render_hook: ResourceLimits,
35}
36
37impl WasmLimitsProfile {
38    pub fn for_point(&self, point: ExtensionPointKind) -> ResourceLimits {
39        match point {
40            ExtensionPointKind::Page => self.page,
41            ExtensionPointKind::Api => self.api,
42            ExtensionPointKind::Job => self.job,
43            ExtensionPointKind::ScheduledJob => self.scheduled_job,
44            ExtensionPointKind::Webhook => self.webhook,
45            ExtensionPointKind::AdminWidget => self.admin_widget,
46            ExtensionPointKind::RenderHook => self.render_hook,
47        }
48    }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct TemplateRuntimeServices {
53    pub customer_app_namespace: TemplateNamespace,
54    pub core_namespace: TemplateNamespace,
55    pub registry: TemplateRegistry,
56    pub runtime: TemplateRuntime,
57}
58
59impl TemplateRuntimeServices {
60    pub fn namespace_chain(
61        &self,
62        module_namespace: Option<&TemplateNamespace>,
63    ) -> Vec<TemplateNamespace> {
64        let mut chain = vec![self.customer_app_namespace.clone()];
65
66        if let Some(module_namespace) = module_namespace {
67            if module_namespace != &self.customer_app_namespace
68                && module_namespace != &self.core_namespace
69            {
70                chain.push(module_namespace.clone());
71            }
72        }
73
74        chain.push(self.core_namespace.clone());
75        chain
76    }
77}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct I18nRuntimeServices {
81    pub default_locale: LocaleTag,
82    pub supported_locales: Vec<LocaleTag>,
83    pub fallback_locale: LocaleTag,
84    pub router: LocaleRouter,
85    pub translations: TranslationRuntime,
86}
87
88impl I18nRuntimeServices {
89    pub fn request_context(&self, requested_locale: Option<&str>) -> LocaleContext {
90        let resolved = requested_locale
91            .and_then(|locale| {
92                self.supported_locales
93                    .iter()
94                    .find(|candidate| candidate.as_str() == locale)
95            })
96            .cloned()
97            .unwrap_or_else(|| self.default_locale.clone());
98
99        LocaleContext::new(
100            resolved.clone(),
101            vec![self.fallback_locale.clone()],
102            currency_for_locale(&resolved),
103            timezone_for_locale(&resolved),
104        )
105    }
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct SeoRuntimeServices {
110    pub canonical_host: String,
111    pub emit_json_ld: bool,
112    pub sitemap_enabled: bool,
113}
114
115impl SeoRuntimeServices {
116    pub fn allows_json_ld(&self) -> bool {
117        self.emit_json_ld
118    }
119
120    pub fn can_emit_metadata(&self, metadata: &HeadMetadata) -> bool {
121        !metadata.canonical_url.is_empty()
122    }
123}
124
125#[derive(Debug, Clone, PartialEq)]
126pub struct A11yRuntimeServices {
127    pub navigation: NavigationContract,
128    pub theme_baseline: ThemeAccessibilityContract,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct CliRuntimeServices {
133    pub customer_app: String,
134    pub baseline_command_count: usize,
135}
136
137impl CliRuntimeServices {
138    pub fn new(customer_app: impl Into<String>, baseline_command_count: usize) -> Self {
139        Self {
140            customer_app: customer_app.into(),
141            baseline_command_count,
142        }
143    }
144}
145
146pub type DataRuntimeServices = DataRuntime;
147pub type JobsRuntimeServices = JobsRuntime;
148pub type ObservabilityRuntimeServices = ObservabilityRuntime;
149pub type TlsRuntimeServices = TlsRuntime;
150
151#[derive(Debug, Clone)]
152pub struct CoreBootstrap {
153    pub registry: ServiceRegistry,
154    pub cache: CacheRuntimeServices,
155    pub browser: BrowserSecurityServices,
156    pub cli: CliRuntimeServices,
157    pub data: DataRuntimeServices,
158    pub jobs: JobsRuntimeServices,
159    pub observability: ObservabilityRuntimeServices,
160    pub i18n: I18nRuntimeServices,
161    pub seo: SeoRuntimeServices,
162    pub a11y: A11yRuntimeServices,
163    pub template: TemplateRuntimeServices,
164    pub tls: TlsRuntimeServices,
165    pub wasm: WasmRuntimeServices,
166}