Skip to main content

a3s_boot/routing/route/
builders.rs

1use super::definition::RouteDefinition;
2use crate::routing::handler::RouteHandler;
3use crate::{BootRequest, BootResponse, HttpMethod, Result, SseEvent};
4use futures_core::Stream;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7use std::future::Future;
8
9impl RouteDefinition {
10    pub fn get<H>(path: impl Into<String>, handler: H) -> Result<Self>
11    where
12        H: RouteHandler,
13    {
14        Self::new(HttpMethod::Get, path, handler)
15    }
16
17    pub fn get_json<H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
18    where
19        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
20        Fut: Future<Output = Result<R>> + Send + 'static,
21        R: Serialize + Send + 'static,
22    {
23        Self::get_json_with_status(path, 200, handler)
24    }
25
26    pub fn get_json_with_status<H, Fut, R>(
27        path: impl Into<String>,
28        status: u16,
29        handler: H,
30    ) -> Result<Self>
31    where
32        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
33        Fut: Future<Output = Result<R>> + Send + 'static,
34        R: Serialize + Send + 'static,
35    {
36        Self::json_response_with_status(HttpMethod::Get, path, status, handler)
37    }
38
39    pub fn sse<H, Fut, S>(path: impl Into<String>, handler: H) -> Result<Self>
40    where
41        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
42        Fut: Future<Output = Result<S>> + Send + 'static,
43        S: Stream<Item = Result<SseEvent>> + Send + 'static,
44    {
45        Self::new(HttpMethod::Get, path, move |request: BootRequest| {
46            let future = request
47                .require_accepts_event_stream()
48                .map(|()| handler(request));
49            async move {
50                let stream = future?.await?;
51                Ok(BootResponse::sse(stream))
52            }
53        })
54    }
55
56    pub fn post<H>(path: impl Into<String>, handler: H) -> Result<Self>
57    where
58        H: RouteHandler,
59    {
60        Self::new(HttpMethod::Post, path, handler)
61    }
62
63    pub fn post_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
64    where
65        T: DeserializeOwned + Send + 'static,
66        H: Fn(T) -> Fut + Send + Sync + 'static,
67        Fut: Future<Output = Result<R>> + Send + 'static,
68        R: Serialize + Send + 'static,
69    {
70        Self::post_json_with_status(path, 200, handler)
71    }
72
73    pub fn post_json_with_status<T, H, Fut, R>(
74        path: impl Into<String>,
75        status: u16,
76        handler: H,
77    ) -> Result<Self>
78    where
79        T: DeserializeOwned + Send + 'static,
80        H: Fn(T) -> Fut + Send + Sync + 'static,
81        Fut: Future<Output = Result<R>> + Send + 'static,
82        R: Serialize + Send + 'static,
83    {
84        Self::json_with_status(HttpMethod::Post, path, status, handler)
85    }
86
87    pub fn put<H>(path: impl Into<String>, handler: H) -> Result<Self>
88    where
89        H: RouteHandler,
90    {
91        Self::new(HttpMethod::Put, path, handler)
92    }
93
94    pub fn put_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
95    where
96        T: DeserializeOwned + Send + 'static,
97        H: Fn(T) -> Fut + Send + Sync + 'static,
98        Fut: Future<Output = Result<R>> + Send + 'static,
99        R: Serialize + Send + 'static,
100    {
101        Self::put_json_with_status(path, 200, handler)
102    }
103
104    pub fn put_json_with_status<T, H, Fut, R>(
105        path: impl Into<String>,
106        status: u16,
107        handler: H,
108    ) -> Result<Self>
109    where
110        T: DeserializeOwned + Send + 'static,
111        H: Fn(T) -> Fut + Send + Sync + 'static,
112        Fut: Future<Output = Result<R>> + Send + 'static,
113        R: Serialize + Send + 'static,
114    {
115        Self::json_with_status(HttpMethod::Put, path, status, handler)
116    }
117
118    pub fn patch<H>(path: impl Into<String>, handler: H) -> Result<Self>
119    where
120        H: RouteHandler,
121    {
122        Self::new(HttpMethod::Patch, path, handler)
123    }
124
125    pub fn patch_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
126    where
127        T: DeserializeOwned + Send + 'static,
128        H: Fn(T) -> Fut + Send + Sync + 'static,
129        Fut: Future<Output = Result<R>> + Send + 'static,
130        R: Serialize + Send + 'static,
131    {
132        Self::patch_json_with_status(path, 200, handler)
133    }
134
135    pub fn patch_json_with_status<T, H, Fut, R>(
136        path: impl Into<String>,
137        status: u16,
138        handler: H,
139    ) -> Result<Self>
140    where
141        T: DeserializeOwned + Send + 'static,
142        H: Fn(T) -> Fut + Send + Sync + 'static,
143        Fut: Future<Output = Result<R>> + Send + 'static,
144        R: Serialize + Send + 'static,
145    {
146        Self::json_with_status(HttpMethod::Patch, path, status, handler)
147    }
148
149    pub fn delete<H>(path: impl Into<String>, handler: H) -> Result<Self>
150    where
151        H: RouteHandler,
152    {
153        Self::new(HttpMethod::Delete, path, handler)
154    }
155
156    pub fn delete_json<H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
157    where
158        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
159        Fut: Future<Output = Result<R>> + Send + 'static,
160        R: Serialize + Send + 'static,
161    {
162        Self::delete_json_with_status(path, 200, handler)
163    }
164
165    pub fn delete_json_with_status<H, Fut, R>(
166        path: impl Into<String>,
167        status: u16,
168        handler: H,
169    ) -> Result<Self>
170    where
171        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
172        Fut: Future<Output = Result<R>> + Send + 'static,
173        R: Serialize + Send + 'static,
174    {
175        Self::json_response_with_status(HttpMethod::Delete, path, status, handler)
176    }
177
178    pub fn options<H>(path: impl Into<String>, handler: H) -> Result<Self>
179    where
180        H: RouteHandler,
181    {
182        Self::new(HttpMethod::Options, path, handler)
183    }
184
185    pub fn head<H>(path: impl Into<String>, handler: H) -> Result<Self>
186    where
187        H: RouteHandler,
188    {
189        Self::new(HttpMethod::Head, path, handler)
190    }
191
192    fn json_with_status<T, H, Fut, R>(
193        method: HttpMethod,
194        path: impl Into<String>,
195        status: u16,
196        handler: H,
197    ) -> Result<Self>
198    where
199        T: DeserializeOwned + Send + 'static,
200        H: Fn(T) -> Fut + Send + Sync + 'static,
201        Fut: Future<Output = Result<R>> + Send + 'static,
202        R: Serialize + Send + 'static,
203    {
204        Self::new(method, path, move |request: BootRequest| {
205            let future = request
206                .require_json_content_type()
207                .and_then(|()| request.require_accepts_json())
208                .and_then(|()| request.json::<T>())
209                .map(&handler);
210            async move {
211                let body = future?.await?;
212                BootResponse::json_with_status(status, &body)
213            }
214        })
215    }
216
217    fn json_response_with_status<H, Fut, R>(
218        method: HttpMethod,
219        path: impl Into<String>,
220        status: u16,
221        handler: H,
222    ) -> Result<Self>
223    where
224        H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
225        Fut: Future<Output = Result<R>> + Send + 'static,
226        R: Serialize + Send + 'static,
227    {
228        Self::new(method, path, move |request: BootRequest| {
229            let future = request.require_accepts_json().map(|()| handler(request));
230            async move {
231                let body = future?.await?;
232                BootResponse::json_with_status(status, &body)
233            }
234        })
235    }
236}