1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
//! Functionality related to defining [Controller]s - containers for functions which handle web
//! requests.
use axum::Router;
use downcast::{downcast_sync, AnySync};
use fxhash::FxHashSet;
#[cfg(test)]
use mockall::automock;
use springtime_di::injectable;
use springtime_di::instance_provider::{ComponentInstancePtr, ErrorPtr};
pub type ServerNameSet = FxHashSet<String>;
/// Main trait for [Components](springtime_di::component::Component) used as controllers -
/// collections of web [handlers](axum::handler::Handler) being functions contained in typical
/// structs. Such approach allows for injecting other components via dependency injection, and
/// therefore, creating advanced applications with proper architecture.
#[injectable]
#[cfg_attr(test, automock)]
pub trait Controller: AnySync {
/// Prefix for all paths contained in the controller, e.g. controller path of `/abc` and handler
/// path of `/xyz` results in final path of `/abc/xyz`.
fn path(&self) -> Option<String> {
None
}
/// Optional list of server names for which given controller should be registered.
fn server_names(&self) -> Option<ServerNameSet> {
None
}
/// Configures a [Router] to handle incoming requests. Passed instance ptr points to the
/// controller component being processed (`Self`).
fn configure_router(
&self,
router: Router,
self_instance_ptr: ComponentInstancePtr<dyn Controller + Send + Sync>,
) -> Result<Router, ErrorPtr>;
/// Creates a [Router] which is then passed to `configure_router`.
fn create_router(&self) -> Result<Router, ErrorPtr>;
/// Adds any post-route configuration to the [Router].
fn post_configure_router(&self, router: Router) -> Result<Router, ErrorPtr>;
}
downcast_sync!(dyn Controller + Send + Sync);