a3s_boot/routing/
handler.rs1use crate::{BootError, BootRequest, BootResponse, BoxFuture, ModuleRef, Result};
2use std::future::Future;
3
4pub trait RouteHandler: Send + Sync + 'static {
6 fn call(&self, request: BootRequest) -> BoxFuture<'static, Result<BootResponse>>;
7}
8
9impl<F, Fut> RouteHandler for F
10where
11 F: Fn(BootRequest) -> Fut + Send + Sync + 'static,
12 Fut: Future<Output = Result<BootResponse>> + Send + 'static,
13{
14 fn call(&self, request: BootRequest) -> BoxFuture<'static, Result<BootResponse>> {
15 Box::pin(self(request))
16 }
17}
18
19pub(crate) struct RequestScopedRouteHandler<F> {
20 factory: F,
21}
22
23impl<F> RequestScopedRouteHandler<F> {
24 pub(crate) fn new(factory: F) -> Self {
25 Self { factory }
26 }
27}
28
29impl<F, H> RouteHandler for RequestScopedRouteHandler<F>
30where
31 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
32 H: RouteHandler,
33{
34 fn call(&self, request: BootRequest) -> BoxFuture<'static, Result<BootResponse>> {
35 let Some(module_ref) = request.module_ref().cloned() else {
36 return Box::pin(async {
37 Err(BootError::Internal(
38 "request-scoped route requires a module context".to_string(),
39 ))
40 });
41 };
42
43 match (self.factory)(&module_ref) {
44 Ok(handler) => handler.call(request),
45 Err(error) => Box::pin(async move { Err(error) }),
46 }
47 }
48}