Skip to main content

cloudillo_core/
app.rs

1//! App state type
2
3use rustls::sign::CertifiedKey;
4use std::{
5	collections::HashMap,
6	path::Path,
7	sync::{Arc, RwLock},
8};
9
10use crate::extensions::Extensions;
11use crate::prelude::*;
12use crate::{abac, request, scheduler, ws_broadcast::BroadcastManager};
13
14use cloudillo_types::auth_adapter::AuthAdapter;
15use cloudillo_types::blob_adapter::BlobAdapter;
16use cloudillo_types::crdt_adapter::CrdtAdapter;
17use cloudillo_types::identity_provider_adapter::IdentityProviderAdapter;
18use cloudillo_types::meta_adapter::MetaAdapter;
19use cloudillo_types::rtdb_adapter::RtdbAdapter;
20use cloudillo_types::worker;
21
22use crate::rate_limit::RateLimitManager;
23use crate::settings::service::SettingsService;
24use crate::settings::types::FrozenSettingsRegistry;
25
26pub const VERSION: &str = env!("CARGO_PKG_VERSION");
27
28#[derive(Debug, Clone, Copy)]
29pub enum ServerMode {
30	Standalone,
31	Proxy,
32	StreamProxy,
33}
34
35pub struct AppState {
36	pub scheduler: Arc<scheduler::Scheduler<App>>,
37	pub worker: Arc<worker::WorkerPool>,
38	pub request: request::Request,
39	pub acme_challenge_map: RwLock<HashMap<Box<str>, Box<str>>>,
40	pub certs: RwLock<HashMap<Box<str>, Arc<CertifiedKey>>>,
41	pub opts: AppBuilderOpts,
42	pub broadcast: BroadcastManager,
43	pub permission_checker: Arc<tokio::sync::RwLock<abac::PermissionChecker>>,
44
45	pub auth_adapter: Arc<dyn AuthAdapter>,
46	pub meta_adapter: Arc<dyn MetaAdapter>,
47	pub blob_adapter: Arc<dyn BlobAdapter>,
48	pub crdt_adapter: Arc<dyn CrdtAdapter>,
49	pub rtdb_adapter: Arc<dyn RtdbAdapter>,
50	pub idp_adapter: Option<Arc<dyn IdentityProviderAdapter>>,
51
52	// Settings subsystem
53	pub settings: Arc<SettingsService>,
54	pub settings_registry: Arc<FrozenSettingsRegistry>,
55
56	// Rate limiter
57	pub rate_limiter: Arc<RateLimitManager>,
58
59	// Type-erased extension map for feature-specific state
60	pub extensions: Extensions,
61}
62
63impl AppState {
64	/// Get a registered extension by type. Returns error if not found.
65	pub fn ext<T: Send + Sync + 'static>(&self) -> ClResult<&T> {
66		self.extensions.get::<T>().ok_or_else(|| {
67			Error::Internal(format!("Extension {} not registered", std::any::type_name::<T>()))
68		})
69	}
70}
71
72pub type App = Arc<AppState>;
73
74pub struct Adapters {
75	pub auth_adapter: Option<Arc<dyn AuthAdapter>>,
76	pub meta_adapter: Option<Arc<dyn MetaAdapter>>,
77	pub blob_adapter: Option<Arc<dyn BlobAdapter>>,
78	pub crdt_adapter: Option<Arc<dyn CrdtAdapter>>,
79	pub rtdb_adapter: Option<Arc<dyn RtdbAdapter>>,
80	pub idp_adapter: Option<Arc<dyn IdentityProviderAdapter>>,
81}
82
83#[derive(Debug)]
84pub struct AppBuilderOpts {
85	pub mode: ServerMode,
86	pub listen: Box<str>,
87	pub listen_http: Option<Box<str>>,
88	pub base_id_tag: Option<Box<str>>,
89	pub base_app_domain: Option<Box<str>>,
90	pub base_password: Option<Box<str>>,
91	pub dist_dir: Box<Path>,
92	pub tmp_dir: Box<Path>,
93	pub acme_email: Option<Box<str>>,
94	pub local_address: Box<[Box<str>]>,
95	/// Disable HTTP caching (for development)
96	pub disable_cache: bool,
97}
98
99// vim: ts=4