xitca_web/app/
object.rs

1use core::marker::PhantomData;
2
3use xitca_http::util::service::router::{IntoObject, PathGen, RouteGen, RouteObject};
4use xitca_service::{Service, object::ServiceObject};
5
6use crate::context::WebContext;
7
8pub type WebObject<C, B, Res, Err> = Box<dyn for<'r> ServiceObject<WebContext<'r, C, B>, Response = Res, Error = Err>>;
9
10impl<C, B, I, Res, Err> IntoObject<I, ()> for WebContext<'_, C, B>
11where
12    C: 'static,
13    B: 'static,
14    I: Service + RouteGen + Send + Sync + 'static,
15    I::Response: for<'r> Service<WebContext<'r, C, B>, Response = Res, Error = Err> + 'static,
16{
17    type Object = RouteObject<(), WebObject<C, B, Res, Err>, I::Error>;
18
19    fn into_object(inner: I) -> Self::Object {
20        struct Builder<I, C, B>(I, PhantomData<fn(C, B)>);
21
22        impl<I, C, B> PathGen for Builder<I, C, B>
23        where
24            I: PathGen,
25        {
26            fn path_gen(&mut self, prefix: &str) -> String {
27                self.0.path_gen(prefix)
28            }
29        }
30
31        impl<I, C, B> RouteGen for Builder<I, C, B>
32        where
33            I: RouteGen,
34        {
35            type Route<R> = I::Route<R>;
36
37            fn route_gen<R>(route: R) -> Self::Route<R> {
38                I::route_gen(route)
39            }
40        }
41
42        impl<C, I, B, Res, Err> Service for Builder<I, C, B>
43        where
44            I: Service + RouteGen + 'static,
45            I::Response: for<'r> Service<WebContext<'r, C, B>, Response = Res, Error = Err> + 'static,
46        {
47            type Response = WebObject<C, B, Res, Err>;
48            type Error = I::Error;
49
50            async fn call(&self, arg: ()) -> Result<Self::Response, Self::Error> {
51                self.0.call(arg).await.map(|s| Box::new(s) as _)
52            }
53        }
54
55        RouteObject(Box::new(Builder(inner, PhantomData)))
56    }
57}