cfg_if::cfg_if! {
if #[cfg(feature = "with-db")] {
use std::path::Path;
use sea_orm::DatabaseConnection;
} else {}
}
use async_trait::async_trait;
use axum::Router as AxumRouter;
use crate::{
boot::{BootResult, StartMode},
config::{self, Config},
controller::AppRoutes,
environment::Environment,
mailer::EmailSender,
task::Tasks,
worker::{Pool, Processor, RedisConnectionManager},
Result,
};
#[derive(Clone)]
#[allow(clippy::module_name_repetitions)]
pub struct AppContext {
pub environment: Environment,
#[cfg(feature = "with-db")]
pub db: DatabaseConnection,
pub redis: Option<Pool<RedisConnectionManager>>,
pub config: Config,
pub mailer: Option<EmailSender>,
}
#[async_trait]
pub trait Hooks {
#[must_use]
fn app_version() -> String {
"dev".to_string()
}
fn app_name() -> &'static str;
async fn boot(mode: StartMode, environment: &Environment) -> Result<BootResult>;
fn init_logger(_config: &config::Config, _env: &Environment) -> Result<bool> {
Ok(false)
}
async fn after_routes(router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
Ok(router)
}
async fn initializers(_ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
Ok(vec![])
}
async fn before_run(_app_context: &AppContext) -> Result<()> {
Ok(())
}
fn routes(_ctx: &AppContext) -> AppRoutes;
fn connect_workers<'a>(p: &'a mut Processor, ctx: &'a AppContext);
fn register_tasks(tasks: &mut Tasks);
#[cfg(feature = "with-db")]
async fn truncate(db: &DatabaseConnection) -> Result<()>;
#[cfg(feature = "with-db")]
async fn seed(db: &DatabaseConnection, path: &Path) -> Result<()>;
}
#[async_trait]
pub trait Initializer: Sync + Send {
fn name(&self) -> String;
async fn before_run(&self, _app_context: &AppContext) -> Result<()> {
Ok(())
}
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
Ok(router)
}
}