use crate::Routes;
use crate::application::ty::{Application, DEFAULT_BIND_ADDR, DEFAULT_PORT, ProxyFn};
use crate::proxy::{ProxyAction, ProxyRequest};
#[cfg(feature = "inertia")]
use crate::inertia::InertiaConfig;
#[cfg(feature = "inertia")]
use crate::inertia::PageContracts;
#[cfg(feature = "pages")]
use crate::pages::{MaintenanceGuard, Pages};
#[cfg(feature = "db")]
use crate::db::DbConfig;
#[cfg(feature = "cache")]
use crate::cache::CacheConfig;
#[cfg(feature = "storage")]
use crate::storage::StorageConfig;
#[cfg(feature = "mail")]
use crate::mail::SmtpConfig;
#[cfg(feature = "jobs")]
use super::jobs_registry::JobsRegistry;
#[cfg(feature = "jobs")]
use crate::jobs::WorkerConfig;
pub struct ApplicationBuilder<S = ()> {
pub(crate) routes: Routes<S>,
pub(crate) proxy: Option<ProxyFn>,
pub(crate) bind_address: String,
pub(crate) port: u16,
#[cfg(feature = "inertia")]
pub(crate) inertia_config: Option<InertiaConfig>,
#[cfg(feature = "inertia")]
pub(crate) page_contracts: Option<PageContracts>,
#[cfg(feature = "pages")]
pub(crate) pages: Option<Pages>,
#[cfg(feature = "pages")]
pub(crate) maintenance_guard: Option<MaintenanceGuard>,
#[cfg(feature = "db")]
pub(crate) database: Option<DbConfig>,
#[cfg(feature = "cache")]
pub(crate) cache_config: Option<CacheConfig>,
#[cfg(feature = "storage")]
pub(crate) storage_config: Option<StorageConfig>,
#[cfg(feature = "mail")]
pub(crate) mail_config: Option<SmtpConfig>,
#[cfg(feature = "jobs")]
pub(crate) jobs_registry: Option<JobsRegistry>,
#[cfg(feature = "jobs")]
pub(crate) worker_config: Option<WorkerConfig>,
#[cfg(feature = "dx")]
pub(crate) error_mapping: Option<crate::pipeline::error_mapping::ErrorMapFn>,
#[cfg(feature = "dev-proxy")]
pub(crate) dev_proxy_endpoint: Option<crate::dev_proxy::endpoint::IpcEndpoint>,
}
impl<S> ApplicationBuilder<S>
where
S: Clone + Send + Sync + 'static,
{
#[must_use]
pub fn proxy<F>(mut self, proxy: F) -> Self
where
F: Fn(ProxyRequest<'_>) -> ProxyAction + Send + Sync + 'static,
{
self.proxy = Some(std::sync::Arc::new(proxy));
self
}
#[must_use]
pub fn bind(mut self, address: impl Into<String>) -> Self {
self.bind_address = address.into();
self
}
#[must_use]
pub fn port(mut self, port: u16) -> Self {
self.port = port;
self
}
#[cfg(feature = "inertia")]
#[must_use]
pub fn inertia(mut self, config: InertiaConfig) -> Self {
self.inertia_config = Some(config);
self
}
#[cfg(feature = "inertia")]
#[must_use]
pub fn page_contracts(mut self, contracts: PageContracts) -> Self {
self.page_contracts = Some(contracts);
self
}
#[cfg(feature = "pages")]
#[must_use]
pub fn pages(mut self, pages: Pages) -> Self {
self.pages = Some(pages);
self
}
#[cfg(feature = "pages")]
#[must_use]
pub fn maintenance(mut self, guard: MaintenanceGuard) -> Self {
self.maintenance_guard = Some(guard);
self
}
#[cfg(feature = "db")]
#[must_use]
pub fn database(mut self, config: DbConfig) -> Self {
self.database = Some(config);
self
}
#[cfg(feature = "cache")]
#[must_use]
pub fn cache(mut self, config: CacheConfig) -> Self {
self.cache_config = Some(config);
self
}
#[cfg(feature = "storage")]
#[must_use]
pub fn storage(mut self, config: StorageConfig) -> Self {
self.storage_config = Some(config);
self
}
#[cfg(feature = "mail")]
#[must_use]
pub fn mail(mut self, config: SmtpConfig) -> Self {
self.mail_config = Some(config);
self
}
#[cfg(feature = "jobs")]
#[must_use]
pub fn jobs(mut self, registry: crate::jobs::Registry) -> Self {
self.jobs_registry = Some(JobsRegistry::Static(registry));
self
}
#[cfg(feature = "jobs")]
#[must_use]
pub fn jobs_with_db<F>(mut self, build: F) -> Self
where
F: Fn(&crate::db::Db) -> crate::jobs::Registry + Send + Sync + 'static,
{
self.jobs_registry = Some(JobsRegistry::WithDb(std::sync::Arc::new(build)));
self
}
#[cfg(feature = "jobs")]
#[must_use]
pub fn worker_config(mut self, config: WorkerConfig) -> Self {
self.worker_config = Some(config);
self
}
#[cfg(feature = "dx")]
#[must_use]
pub fn error_mapping<F>(mut self, f: F) -> Self
where
F: Fn(crate::axum::response::Response) -> crate::axum::response::Response
+ Send
+ Sync
+ 'static,
{
self.error_mapping = Some(crate::pipeline::error_mapping::ErrorMapFn::new(f));
self
}
#[cfg(feature = "dev-proxy")]
#[must_use]
pub fn dev_proxy_endpoint(mut self, endpoint: Option<std::path::PathBuf>) -> Self {
self.dev_proxy_endpoint = endpoint.map(crate::dev_proxy::endpoint::IpcEndpoint::new);
self
}
#[must_use]
pub fn state(self, state: S) -> ApplicationBuilder<()> {
ApplicationBuilder {
routes: self.routes.with_state(state),
proxy: self.proxy,
bind_address: self.bind_address,
port: self.port,
#[cfg(feature = "inertia")]
inertia_config: self.inertia_config,
#[cfg(feature = "inertia")]
page_contracts: self.page_contracts,
#[cfg(feature = "pages")]
pages: self.pages,
#[cfg(feature = "pages")]
maintenance_guard: self.maintenance_guard,
#[cfg(feature = "db")]
database: self.database,
#[cfg(feature = "cache")]
cache_config: self.cache_config,
#[cfg(feature = "storage")]
storage_config: self.storage_config,
#[cfg(feature = "mail")]
mail_config: self.mail_config,
#[cfg(feature = "jobs")]
jobs_registry: self.jobs_registry,
#[cfg(feature = "jobs")]
worker_config: self.worker_config,
#[cfg(feature = "dx")]
error_mapping: self.error_mapping,
#[cfg(feature = "dev-proxy")]
dev_proxy_endpoint: self.dev_proxy_endpoint,
}
}
#[must_use]
pub fn build(self) -> Application<S> {
Application {
routes: self.routes,
proxy: self.proxy,
bind_address: self.bind_address,
port: self.port,
#[cfg(feature = "inertia")]
inertia_config: self.inertia_config,
#[cfg(feature = "inertia")]
page_contracts: self.page_contracts,
#[cfg(feature = "pages")]
pages: self.pages,
#[cfg(feature = "pages")]
maintenance_guard: self.maintenance_guard,
#[cfg(feature = "db")]
database: self.database,
#[cfg(feature = "cache")]
cache_config: self.cache_config,
#[cfg(feature = "storage")]
storage_config: self.storage_config,
#[cfg(feature = "mail")]
mail_config: self.mail_config,
#[cfg(feature = "jobs")]
jobs_registry: self.jobs_registry,
#[cfg(feature = "jobs")]
worker_config: self.worker_config,
#[cfg(feature = "dx")]
error_mapping: self.error_mapping,
#[cfg(feature = "dev-proxy")]
dev_proxy_endpoint: self.dev_proxy_endpoint,
}
}
}
impl ApplicationBuilder<()> {
#[must_use]
pub fn new() -> Self {
Self {
routes: Routes::new(),
proxy: None,
bind_address: DEFAULT_BIND_ADDR.to_owned(),
port: DEFAULT_PORT,
#[cfg(feature = "inertia")]
inertia_config: None,
#[cfg(feature = "inertia")]
page_contracts: None,
#[cfg(feature = "pages")]
pages: None,
#[cfg(feature = "pages")]
maintenance_guard: None,
#[cfg(feature = "db")]
database: None,
#[cfg(feature = "cache")]
cache_config: None,
#[cfg(feature = "storage")]
storage_config: None,
#[cfg(feature = "mail")]
mail_config: None,
#[cfg(feature = "jobs")]
jobs_registry: None,
#[cfg(feature = "jobs")]
worker_config: None,
#[cfg(feature = "dx")]
error_mapping: None,
#[cfg(feature = "dev-proxy")]
dev_proxy_endpoint: None,
}
}
}
impl Default for ApplicationBuilder<()> {
fn default() -> Self {
Self::new()
}
}
impl<S> ApplicationBuilder<S> {
#[must_use]
pub fn routes<S2>(self, routes: Routes<S2>) -> ApplicationBuilder<S2> {
ApplicationBuilder {
routes,
proxy: self.proxy,
bind_address: self.bind_address,
port: self.port,
#[cfg(feature = "inertia")]
inertia_config: self.inertia_config,
#[cfg(feature = "inertia")]
page_contracts: self.page_contracts,
#[cfg(feature = "pages")]
pages: self.pages,
#[cfg(feature = "pages")]
maintenance_guard: self.maintenance_guard,
#[cfg(feature = "db")]
database: self.database,
#[cfg(feature = "cache")]
cache_config: self.cache_config,
#[cfg(feature = "storage")]
storage_config: self.storage_config,
#[cfg(feature = "mail")]
mail_config: self.mail_config,
#[cfg(feature = "jobs")]
jobs_registry: self.jobs_registry,
#[cfg(feature = "jobs")]
worker_config: self.worker_config,
#[cfg(feature = "dx")]
error_mapping: self.error_mapping,
#[cfg(feature = "dev-proxy")]
dev_proxy_endpoint: self.dev_proxy_endpoint,
}
}
}