pub mod error; pub mod health; use std::sync::Arc; use config::AppConfig; pub use error::BootstrapError; #[derive(Clone)] pub struct AppState { pub database: Arc, pub redis: cache::AppRedis, pub cache: cache::Cache, pub storage: Arc, pub config: AppConfig, pub health: health::HealthCache, pub mail: Option, pub events: Option, } impl AppState { pub async fn load() -> Result { let config = config::AppConfig::load().map_err(|e| BootstrapError::InvalidConfig(e.to_string()))?; Self::with_config(config).await } pub async fn with_config(config: AppConfig) -> Result { let database: Arc = Arc::new(db::AppDatabase::connect(config.database.clone()).await?); Self::with_identity(config, database, None, None).await } pub async fn with_identity( config: AppConfig, database: Arc, mail: Option, events: Option, ) -> Result { let conn = cache::CacheConn::init(&config.redis).await?; let redis = cache::AppRedis::from_conn(conn.clone()); let cache = cache::Cache::from_conn(conn, &config.redis); let storage: Arc = Arc::new(storage::S3Client::new(&config.s3)?); Ok(Self::from_parts( database, redis, cache, storage, config, mail, events, )) } #[allow(clippy::too_many_arguments)] pub fn from_parts( database: Arc, redis: cache::AppRedis, cache: cache::Cache, storage: Arc, config: AppConfig, mail: Option, events: Option, ) -> Self { Self { database, redis, cache, storage, config, health: health::HealthCache::default(), mail, events, } } }