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