1use std::num::NonZeroUsize;
2use std::sync::Arc;
3
4use sofie_auth::SigningKeys;
5use sofie_core::Result;
6
7use crate::health::{Dependency, Readiness};
8use crate::{Area, RequestContext};
9
10const UNNAMED: &str = "sofie";
11
12#[derive(Default)]
13pub struct Serving {
14 pub(crate) name: Option<&'static str>,
15 pub(crate) max_connections: Option<NonZeroUsize>,
16 pub(crate) keys: Option<SigningKeys>,
17 pub(crate) dependencies: Vec<Dependency>,
18 pub(crate) readiness: Readiness,
19 #[cfg(feature = "trusted-proxies")]
20 pub(crate) proxies: crate::TrustedProxies,
21 #[cfg(feature = "metrics")]
22 pub(crate) metrics_token: Option<crate::MetricsToken>,
23 #[cfg(feature = "browser-telemetry")]
24 pub(crate) browser_sample: crate::BrowserSample,
25 #[cfg(feature = "shield")]
26 pub(crate) shield: crate::Shield,
27 #[cfg(feature = "cors")]
28 pub(crate) cors_origins: crate::CorsOrigins,
29 #[cfg(feature = "storage")]
30 pub(crate) storage: Option<sofie_storage::Storage>,
31 #[cfg(feature = "tls")]
32 pub(crate) tls: Option<crate::Tls>,
33 #[cfg(feature = "engine")]
34 pub(crate) content_security: std::collections::HashMap<&'static str, crate::ContentSecurity>,
35 #[cfg(feature = "engine")]
36 pub(crate) content_security_everywhere: crate::ContentSecurity,
37}
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41pub struct AppName(&'static str);
42
43impl AppName {
44 pub(crate) fn of_serving(serving: &Serving) -> Self {
45 Self(serving.name.unwrap_or(UNNAMED))
46 }
47
48 #[must_use]
49 pub fn as_str(&self) -> &'static str {
50 self.0
51 }
52}
53
54impl std::fmt::Display for AppName {
55 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 formatter.write_str(self.0)
57 }
58}
59
60impl<A: Area, M> sofie_db::Resolve<RequestContext<A, M>> for AppName {
61 fn resolve(context: &mut RequestContext<A, M>) -> impl Future<Output = Result<Self>> + Send {
62 std::future::ready(Ok(context.matched.app))
63 }
64}
65
66impl Serving {
67 #[must_use]
70 pub fn named(mut self, name: &'static str) -> Self {
71 self.name = Some(name);
72 self
73 }
74
75 #[must_use]
77 pub fn signing_keys(mut self, keys: SigningKeys) -> Self {
78 self.keys = Some(keys);
79 self
80 }
81
82 #[must_use]
84 pub fn max_connections(mut self, limit: NonZeroUsize) -> Self {
85 self.max_connections = Some(limit);
86 self
87 }
88
89 #[must_use]
91 pub fn dependency<F>(
92 mut self,
93 name: &'static str,
94 check: impl Fn() -> F + Send + Sync + 'static,
95 ) -> Self
96 where
97 F: Future<Output = Result<()>> + Send + 'static,
98 {
99 self.dependencies.push(Dependency {
100 name,
101 check: Arc::new(move || Box::pin(check())),
102 });
103 self
104 }
105}