rustapi_core/app/
dispatcher.rs1use crate::interceptor::InterceptorChain;
2use crate::middleware::{BoxedNext, LayerStack};
3use crate::router::Router;
4use crate::{Request, Response};
5use http::Extensions;
6use std::sync::Arc;
7
8#[derive(Clone)]
13pub struct RequestDispatcher {
14 pub(super) router: Arc<Router>,
15 pub(super) layers: LayerStack,
16 pub(super) interceptors: InterceptorChain,
17}
18
19impl RequestDispatcher {
20 pub fn state_ref(&self) -> Arc<Extensions> {
23 self.router.state_ref()
24 }
25
26 pub async fn dispatch(&self, request: Request) -> Response {
31 let req = self.interceptors.intercept_request(request);
32
33 let path = req.path().to_owned();
34 let method = req.method().clone();
35
36 let response = if self.layers.is_empty() {
37 crate::server::route_request_direct(&self.router, req, &path, &method).await
38 } else {
39 let router = self.router.clone();
40 let p = path.clone();
41 let m = method.clone();
42
43 let routing_handler: BoxedNext = Arc::new(move |r: Request| {
44 let router = router.clone();
45 let pp = p.clone();
46 let mm = m.clone();
47 Box::pin(async move { crate::server::route_request(&router, r, &pp, &mm).await })
48 });
49
50 self.layers.execute(req, routing_handler).await
51 };
52
53 self.interceptors.intercept_response(response)
54 }
55}