alux_http_direct/
handler.rs1use crate::input::DirectInputsAlg;
4use crate::input::{
5 DirectBodyInput, DirectCookieInput, DirectFormInput, DirectHeadInput, DirectHeaderInput, DirectMultipartInput,
6 DirectPathInput, DirectQueryInput, DirectRawBodyInput,
7};
8use crate::route::{DirectEndpoint, DirectRoute, DirectRouteImpl, DirectSelector};
9use crate::{DirectRequest, DirectResponse};
10use alux_ext::{ApplyAlg, HandlerContextAlg, OperationAlg};
11use alux_http::{
12 HandlerAlg, HandlerEndpointAlg, HttpInputAlg, HttpMethod, HttpSelectorAlg, OutputAlg, OutputKindAlg, RouteAlg,
13 RoutePath, SelectorAlg,
14};
15use std::sync::Arc;
16
17pub struct DirectHandlerImpl<Context> {
19 context: Arc<Context>,
20}
21
22impl<Context> DirectHandlerImpl<Context> {
23 pub fn new(context: Context) -> Self {
25 Self { context: Arc::new(context) }
26 }
27
28 pub fn from_shared(context: Arc<Context>) -> Self {
30 Self { context }
31 }
32}
33
34impl<Context> HandlerContextAlg<Context> for DirectHandlerImpl<Context>
35where
36 Context: Send + Sync + 'static,
37{
38 type Handle = Arc<Context>;
39}
40
41impl<Context> HandlerAlg for DirectHandlerImpl<Context> {
42 type Endpoint = DirectEndpoint;
43}
44
45impl<Context> HttpInputAlg for DirectHandlerImpl<Context> {
46 type Path<I> = DirectPathInput<I>;
47 type Query<I> = DirectQueryInput<I>;
48 type Body<I> = DirectBodyInput<I>;
49 type Form<I> = DirectFormInput<I>;
50 type Multipart<I> = DirectMultipartInput<I>;
51 type RawBody<I> = DirectRawBodyInput<I>;
52 type Header<I> = DirectHeaderInput<I>;
55 type Cookie<I> = DirectCookieInput<I>;
56 type Auth<I> = DirectHeaderInput<I>;
57 type Context<I> = DirectHeadInput<I>;
58}
59
60impl<Context, Inputs, Args, Transform, Answering, Output>
61 HandlerEndpointAlg<Arc<Context>, Inputs, Args, Transform, Output> for DirectHandlerImpl<Context>
62where
63 Context: Send + Sync + 'static,
64 Inputs: DirectInputsAlg<Args> + Send + 'static,
65 Args: Send + 'static,
66 Output: Send + 'static,
67 Transform: OutputKindAlg<Self, Output, Transform = Answering> + Send + 'static,
68 Answering: OutputAlg<Output, Output = DirectResponse>,
69{
70 fn finish_handler<Handler>(&self, handler: Handler) -> <Self as HandlerAlg>::Endpoint
71 where
72 Handler: OperationAlg + ApplyAlg<Arc<Context>, Args, Output = Output> + Send + Sync + 'static,
73 {
74 let context = Arc::clone(&self.context);
75 let handler = Arc::new(handler);
76 DirectEndpoint::new(move |request: DirectRequest, captures: Vec<String>| {
77 let context = Arc::clone(&context);
78 let handler = Arc::clone(&handler);
79 Box::pin(async move {
80 let inputs = match Inputs::extract(&request, &captures).await {
81 Ok(inputs) => inputs,
82 Err(error) => return error.into(),
83 };
84 let output = handler.apply(context, inputs).await;
85
86 Answering::output(output)
87 })
88 })
89 }
90}
91
92impl<Context> SelectorAlg for DirectHandlerImpl<Context> {
93 type Selector = DirectSelector;
94
95 fn identity(&self) -> Self::Selector {
96 SelectorAlg::identity(&DirectRouteImpl)
97 }
98
99 fn compose(&self, first: Self::Selector, second: Self::Selector) -> Self::Selector {
100 SelectorAlg::compose(&DirectRouteImpl, first, second)
101 }
102}
103
104impl<Context> RouteAlg for DirectHandlerImpl<Context> {
105 type Route = DirectRoute;
106 type Selector = DirectSelector;
107 type Endpoint = DirectEndpoint;
108
109 fn initial(&self) -> Self::Route {
110 RouteAlg::initial(&DirectRouteImpl)
111 }
112
113 fn coproduct(&self, left: Self::Route, right: Self::Route) -> Self::Route {
114 RouteAlg::coproduct(&DirectRouteImpl, left, right)
115 }
116
117 fn precompose(&self, selector: Self::Selector, route: Self::Route) -> Self::Route {
118 RouteAlg::precompose(&DirectRouteImpl, selector, route)
119 }
120
121 fn lift(&self, endpoint: Self::Endpoint) -> Self::Route {
122 RouteAlg::lift(&DirectRouteImpl, endpoint)
123 }
124}
125
126impl<Context> HttpSelectorAlg for DirectHandlerImpl<Context> {
127 type Selector = DirectSelector;
128
129 fn http_method(&self, method: HttpMethod) -> Self::Selector {
130 HttpSelectorAlg::http_method(&DirectRouteImpl, method)
131 }
132
133 fn http_path(&self, path: &RoutePath) -> Self::Selector {
134 HttpSelectorAlg::http_path(&DirectRouteImpl, path)
135 }
136
137 fn http_prefix(&self, prefix: &RoutePath) -> Self::Selector {
138 HttpSelectorAlg::http_prefix(&DirectRouteImpl, prefix)
139 }
140}