1use bytes::Bytes;
2use futures::{Sink, Stream};
3use http::Method;
4use std::{borrow::Cow, future::Future};
5
6#[cfg(feature = "actix-no-default")]
8pub mod actix;
9#[cfg(feature = "axum-no-default")]
11pub mod axum;
12#[cfg(feature = "browser")]
14pub mod browser;
15#[cfg(feature = "generic")]
16pub mod generic;
17#[cfg(feature = "reqwest")]
19pub mod reqwest;
20
21pub trait ClientReq<E>
23where
24 Self: Sized,
25{
26 type FormData;
28
29 fn try_new_req_query(
31 path: &str,
32 content_type: &str,
33 accepts: &str,
34 query: &str,
35 method: Method,
36 ) -> Result<Self, E>;
37
38 fn try_new_req_text(
40 path: &str,
41 content_type: &str,
42 accepts: &str,
43 body: String,
44 method: Method,
45 ) -> Result<Self, E>;
46
47 fn try_new_req_bytes(
49 path: &str,
50 content_type: &str,
51 accepts: &str,
52 body: Bytes,
53 method: Method,
54 ) -> Result<Self, E>;
55
56 fn try_new_req_form_data(
58 path: &str,
59 accepts: &str,
60 content_type: &str,
61 body: Self::FormData,
62 method: Method,
63 ) -> Result<Self, E>;
64
65 fn try_new_req_multipart(
67 path: &str,
68 accepts: &str,
69 body: Self::FormData,
70 method: Method,
71 ) -> Result<Self, E>;
72
73 fn try_new_req_streaming(
75 path: &str,
76 accepts: &str,
77 content_type: &str,
78 body: impl Stream<Item = Bytes> + Send + 'static,
79 method: Method,
80 ) -> Result<Self, E>;
81
82 fn try_new_get(
84 path: &str,
85 content_type: &str,
86 accepts: &str,
87 query: &str,
88 ) -> Result<Self, E> {
89 Self::try_new_req_query(path, content_type, accepts, query, Method::GET)
90 }
91
92 fn try_new_delete(
96 path: &str,
97 content_type: &str,
98 accepts: &str,
99 query: &str,
100 ) -> Result<Self, E> {
101 Self::try_new_req_query(
102 path,
103 content_type,
104 accepts,
105 query,
106 Method::DELETE,
107 )
108 }
109
110 fn try_new_post(
112 path: &str,
113 content_type: &str,
114 accepts: &str,
115 body: String,
116 ) -> Result<Self, E> {
117 Self::try_new_req_text(path, content_type, accepts, body, Method::POST)
118 }
119
120 fn try_new_patch(
124 path: &str,
125 content_type: &str,
126 accepts: &str,
127 body: String,
128 ) -> Result<Self, E> {
129 Self::try_new_req_text(path, content_type, accepts, body, Method::PATCH)
130 }
131
132 fn try_new_put(
136 path: &str,
137 content_type: &str,
138 accepts: &str,
139 body: String,
140 ) -> Result<Self, E> {
141 Self::try_new_req_text(path, content_type, accepts, body, Method::PUT)
142 }
143
144 fn try_new_post_bytes(
146 path: &str,
147 content_type: &str,
148 accepts: &str,
149 body: Bytes,
150 ) -> Result<Self, E> {
151 Self::try_new_req_bytes(path, content_type, accepts, body, Method::POST)
152 }
153
154 fn try_new_patch_bytes(
158 path: &str,
159 content_type: &str,
160 accepts: &str,
161 body: Bytes,
162 ) -> Result<Self, E> {
163 Self::try_new_req_bytes(
164 path,
165 content_type,
166 accepts,
167 body,
168 Method::PATCH,
169 )
170 }
171
172 fn try_new_put_bytes(
176 path: &str,
177 content_type: &str,
178 accepts: &str,
179 body: Bytes,
180 ) -> Result<Self, E> {
181 Self::try_new_req_bytes(path, content_type, accepts, body, Method::PUT)
182 }
183
184 fn try_new_post_form_data(
186 path: &str,
187 accepts: &str,
188 content_type: &str,
189 body: Self::FormData,
190 ) -> Result<Self, E> {
191 Self::try_new_req_form_data(
192 path,
193 accepts,
194 content_type,
195 body,
196 Method::POST,
197 )
198 }
199
200 fn try_new_patch_form_data(
204 path: &str,
205 accepts: &str,
206 content_type: &str,
207 body: Self::FormData,
208 ) -> Result<Self, E> {
209 Self::try_new_req_form_data(
210 path,
211 accepts,
212 content_type,
213 body,
214 Method::PATCH,
215 )
216 }
217
218 fn try_new_put_form_data(
222 path: &str,
223 accepts: &str,
224 content_type: &str,
225 body: Self::FormData,
226 ) -> Result<Self, E> {
227 Self::try_new_req_form_data(
228 path,
229 accepts,
230 content_type,
231 body,
232 Method::PUT,
233 )
234 }
235
236 fn try_new_post_multipart(
238 path: &str,
239 accepts: &str,
240 body: Self::FormData,
241 ) -> Result<Self, E> {
242 Self::try_new_req_multipart(path, accepts, body, Method::POST)
243 }
244
245 fn try_new_patch_multipart(
249 path: &str,
250 accepts: &str,
251 body: Self::FormData,
252 ) -> Result<Self, E> {
253 Self::try_new_req_multipart(path, accepts, body, Method::PATCH)
254 }
255
256 fn try_new_put_multipart(
260 path: &str,
261 accepts: &str,
262 body: Self::FormData,
263 ) -> Result<Self, E> {
264 Self::try_new_req_multipart(path, accepts, body, Method::PUT)
265 }
266
267 fn try_new_post_streaming(
269 path: &str,
270 accepts: &str,
271 content_type: &str,
272 body: impl Stream<Item = Bytes> + Send + 'static,
273 ) -> Result<Self, E> {
274 Self::try_new_req_streaming(
275 path,
276 accepts,
277 content_type,
278 body,
279 Method::POST,
280 )
281 }
282
283 fn try_new_patch_streaming(
287 path: &str,
288 accepts: &str,
289 content_type: &str,
290 body: impl Stream<Item = Bytes> + Send + 'static,
291 ) -> Result<Self, E> {
292 Self::try_new_req_streaming(
293 path,
294 accepts,
295 content_type,
296 body,
297 Method::PATCH,
298 )
299 }
300
301 fn try_new_put_streaming(
305 path: &str,
306 accepts: &str,
307 content_type: &str,
308 body: impl Stream<Item = Bytes> + Send + 'static,
309 ) -> Result<Self, E> {
310 Self::try_new_req_streaming(
311 path,
312 accepts,
313 content_type,
314 body,
315 Method::PUT,
316 )
317 }
318}
319
320pub trait Req<Error, InputStreamError = Error, OutputStreamError = Error>
322where
323 Self: Sized,
324{
325 type WebsocketResponse: Send;
327
328 fn as_query(&self) -> Option<&str>;
330
331 fn to_content_type(&self) -> Option<Cow<'_, str>>;
333
334 fn accepts(&self) -> Option<Cow<'_, str>>;
336
337 fn referer(&self) -> Option<Cow<'_, str>>;
339
340 fn try_into_bytes(
342 self,
343 ) -> impl Future<Output = Result<Bytes, Error>> + Send;
344
345 fn try_into_string(
347 self,
348 ) -> impl Future<Output = Result<String, Error>> + Send;
349
350 fn try_into_stream(
352 self,
353 ) -> Result<impl Stream<Item = Result<Bytes, Bytes>> + Send + 'static, Error>;
354
355 #[allow(clippy::type_complexity)]
357 fn try_into_websocket(
358 self,
359 ) -> impl Future<
360 Output = Result<
361 (
362 impl Stream<Item = Result<Bytes, Bytes>> + Send + 'static,
363 impl Sink<Bytes> + Send + 'static,
364 Self::WebsocketResponse,
365 ),
366 Error,
367 >,
368 > + Send;
369}
370
371pub struct BrowserMockReq;
374
375impl<Error, InputStreamError, OutputStreamError>
376 Req<Error, InputStreamError, OutputStreamError> for BrowserMockReq
377where
378 Error: Send + 'static,
379 InputStreamError: Send + 'static,
380 OutputStreamError: Send + 'static,
381{
382 type WebsocketResponse = crate::response::BrowserMockRes;
383
384 fn as_query(&self) -> Option<&str> {
385 unreachable!()
386 }
387
388 fn to_content_type(&self) -> Option<Cow<'_, str>> {
389 unreachable!()
390 }
391
392 fn accepts(&self) -> Option<Cow<'_, str>> {
393 unreachable!()
394 }
395
396 fn referer(&self) -> Option<Cow<'_, str>> {
397 unreachable!()
398 }
399 async fn try_into_bytes(self) -> Result<Bytes, Error> {
400 unreachable!()
401 }
402
403 async fn try_into_string(self) -> Result<String, Error> {
404 unreachable!()
405 }
406
407 fn try_into_stream(
408 self,
409 ) -> Result<impl Stream<Item = Result<Bytes, Bytes>> + Send, Error> {
410 Ok(futures::stream::once(async { unreachable!() }))
411 }
412
413 async fn try_into_websocket(
414 self,
415 ) -> Result<
416 (
417 impl Stream<Item = Result<Bytes, Bytes>> + Send + 'static,
418 impl Sink<Bytes> + Send + 'static,
419 Self::WebsocketResponse,
420 ),
421 Error,
422 > {
423 #[allow(unreachable_code)]
424 Err::<
425 (
426 futures::stream::Once<std::future::Ready<Result<Bytes, Bytes>>>,
427 futures::sink::Drain<Bytes>,
428 Self::WebsocketResponse,
429 ),
430 _,
431 >(unreachable!())
432 }
433}