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}