1use crate::io::{Error, ErrorType, Read, Write};
2
3pub use super::{Headers, Method, Status};
4
5#[derive(Debug)]
6#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7pub struct Client<C>(C);
8
9impl<C> Client<C>
10where
11 C: Connection,
12{
13 pub fn wrap(connection: C) -> Self {
14 if connection.is_request_initiated() || connection.is_response_initiated() {
15 panic!("connection is not in initial phase");
16 }
17
18 Self(connection)
19 }
20
21 pub fn connection(&mut self) -> &mut C {
22 &mut self.0
23 }
24
25 pub fn release(self) -> C {
26 self.0
27 }
28
29 pub fn get<'a>(&'a mut self, uri: &'a str) -> Result<Request<&'a mut C>, C::Error> {
30 self.request(Method::Get, uri, &[])
31 }
32
33 pub fn post<'a>(
34 &'a mut self,
35 uri: &'a str,
36 headers: &'a [(&'a str, &'a str)],
37 ) -> Result<Request<&'a mut C>, C::Error> {
38 self.request(Method::Post, uri, headers)
39 }
40
41 pub fn put<'a>(
42 &'a mut self,
43 uri: &'a str,
44 headers: &'a [(&'a str, &'a str)],
45 ) -> Result<Request<&'a mut C>, C::Error> {
46 self.request(Method::Put, uri, headers)
47 }
48
49 pub fn delete<'a>(&'a mut self, uri: &'a str) -> Result<Request<&'a mut C>, C::Error> {
50 self.request(Method::Delete, uri, &[])
51 }
52
53 pub fn request<'a>(
54 &'a mut self,
55 method: Method,
56 uri: &'a str,
57 headers: &'a [(&'a str, &'a str)],
58 ) -> Result<Request<&'a mut C>, C::Error> {
59 self.0.initiate_request(method, uri, headers)?;
60
61 Ok(Request::wrap(&mut self.0))
62 }
63
64 pub fn raw_connection(&mut self) -> Result<&mut C::RawConnection, C::Error> {
65 self.0.raw_connection()
66 }
67}
68
69impl<C> ErrorType for Client<C>
70where
71 C: ErrorType,
72{
73 type Error = C::Error;
74}
75
76#[derive(Debug)]
77#[cfg_attr(feature = "defmt", derive(defmt::Format))]
78pub struct Request<C>(C);
79
80impl<C> Request<C>
81where
82 C: Connection,
83{
84 pub fn wrap(connection: C) -> Request<C> {
85 if !connection.is_request_initiated() {
86 panic!("connection is not in request phase");
87 }
88
89 Request(connection)
90 }
91
92 pub fn submit(mut self) -> Result<Response<C>, C::Error> {
93 self.0.initiate_response()?;
94
95 Ok(Response(self.0))
96 }
97
98 pub fn connection(&mut self) -> &mut C {
99 &mut self.0
100 }
101
102 pub fn release(self) -> C {
103 self.0
104 }
105
106 pub fn write(&mut self, buf: &[u8]) -> Result<usize, C::Error> {
107 self.0.write(buf)
108 }
109
110 pub fn flush(&mut self) -> Result<(), C::Error> {
111 self.0.flush()
112 }
113}
114
115impl<C> ErrorType for Request<C>
116where
117 C: ErrorType,
118{
119 type Error = C::Error;
120}
121
122impl<C> Write for Request<C>
123where
124 C: Connection,
125{
126 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
127 self.0.write(buf)
128 }
129
130 fn flush(&mut self) -> Result<(), Self::Error> {
131 self.0.flush()
132 }
133}
134
135#[derive(Debug)]
136#[cfg_attr(feature = "defmt", derive(defmt::Format))]
137pub struct Response<C>(C);
138
139impl<C> Response<C>
140where
141 C: Connection,
142{
143 pub fn wrap(connection: C) -> Response<C> {
144 if !connection.is_response_initiated() {
145 panic!("connection is not in response phase");
146 }
147
148 Response(connection)
149 }
150
151 pub fn split(&mut self) -> (&C::Headers, &mut C::Read) {
152 self.0.split()
153 }
154
155 pub fn connection(&mut self) -> &mut C {
156 &mut self.0
157 }
158
159 pub fn release(self) -> C {
160 self.0
161 }
162
163 pub fn status(&self) -> u16 {
164 self.0.status()
165 }
166
167 pub fn status_message(&self) -> Option<&'_ str> {
168 self.0.status_message()
169 }
170
171 pub fn header(&self, name: &str) -> Option<&'_ str> {
172 self.0.header(name)
173 }
174
175 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, C::Error> {
176 self.0.read(buf)
177 }
178}
179
180impl<C> Status for Response<C>
181where
182 C: Connection,
183{
184 fn status(&self) -> u16 {
185 Response::status(self)
186 }
187
188 fn status_message(&self) -> Option<&'_ str> {
189 Response::status_message(self)
190 }
191}
192
193impl<C> Headers for Response<C>
194where
195 C: Connection,
196{
197 fn header(&self, name: &str) -> Option<&'_ str> {
198 Response::header(self, name)
199 }
200}
201
202impl<C> ErrorType for Response<C>
203where
204 C: ErrorType,
205{
206 type Error = C::Error;
207}
208
209impl<C> Read for Response<C>
210where
211 C: Connection,
212{
213 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
214 Response::read(self, buf)
215 }
216}
217
218pub trait Connection: Status + Headers + Read + Write {
219 type Headers: Status + Headers;
220
221 type Read: Read<Error = Self::Error>;
222
223 type RawConnectionError: Error;
224
225 type RawConnection: Read<Error = Self::RawConnectionError>
226 + Write<Error = Self::RawConnectionError>;
227
228 fn initiate_request<'a>(
229 &'a mut self,
230 method: Method,
231 uri: &'a str,
232 headers: &'a [(&'a str, &'a str)],
233 ) -> Result<(), Self::Error>;
234
235 fn is_request_initiated(&self) -> bool;
236
237 fn initiate_response(&mut self) -> Result<(), Self::Error>;
238
239 fn is_response_initiated(&self) -> bool;
240
241 fn split(&mut self) -> (&Self::Headers, &mut Self::Read);
242
243 fn raw_connection(&mut self) -> Result<&mut Self::RawConnection, Self::Error>;
244}
245
246impl<C> Connection for &mut C
247where
248 C: Connection,
249{
250 type Headers = C::Headers;
251
252 type Read = C::Read;
253
254 type RawConnectionError = C::RawConnectionError;
255
256 type RawConnection = C::RawConnection;
257
258 fn initiate_request<'a>(
259 &'a mut self,
260 method: Method,
261 uri: &'a str,
262 headers: &'a [(&'a str, &'a str)],
263 ) -> Result<(), Self::Error> {
264 (*self).initiate_request(method, uri, headers)
265 }
266
267 fn is_request_initiated(&self) -> bool {
268 (**self).is_request_initiated()
269 }
270
271 fn initiate_response(&mut self) -> Result<(), Self::Error> {
272 (*self).initiate_response()
273 }
274
275 fn is_response_initiated(&self) -> bool {
276 (**self).is_response_initiated()
277 }
278
279 fn split(&mut self) -> (&Self::Headers, &mut Self::Read) {
280 (*self).split()
281 }
282
283 fn raw_connection(&mut self) -> Result<&mut Self::RawConnection, Self::Error> {
284 (*self).raw_connection()
285 }
286}
287
288pub mod asynch {
289 use crate::io::{asynch::Read, asynch::Write, Error, ErrorType};
290
291 pub use crate::http::asynch::*;
292 pub use crate::http::{Headers, Method, Status};
293
294 #[derive(Debug)]
295 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
296 pub struct Client<C>(C);
297
298 impl<C> Client<C>
299 where
300 C: Connection,
301 {
302 pub fn wrap(connection: C) -> Self {
303 if connection.is_request_initiated() || connection.is_response_initiated() {
304 panic!("connection is not in initial phase");
305 }
306
307 Self(connection)
308 }
309
310 pub fn connection(&mut self) -> &mut C {
311 &mut self.0
312 }
313
314 pub fn release(self) -> C {
315 self.0
316 }
317
318 pub async fn get<'a>(&'a mut self, uri: &'a str) -> Result<Request<&'a mut C>, C::Error> {
319 self.request(Method::Get, uri, &[]).await
320 }
321
322 pub async fn post<'a>(
323 &'a mut self,
324 uri: &'a str,
325 headers: &'a [(&'a str, &'a str)],
326 ) -> Result<Request<&'a mut C>, C::Error> {
327 self.request(Method::Post, uri, headers).await
328 }
329
330 pub async fn put<'a>(
331 &'a mut self,
332 uri: &'a str,
333 headers: &'a [(&'a str, &'a str)],
334 ) -> Result<Request<&'a mut C>, C::Error> {
335 self.request(Method::Put, uri, headers).await
336 }
337
338 pub async fn delete<'a>(
339 &'a mut self,
340 uri: &'a str,
341 ) -> Result<Request<&'a mut C>, C::Error> {
342 self.request(Method::Delete, uri, &[]).await
343 }
344
345 pub async fn request<'a>(
346 &'a mut self,
347 method: Method,
348 uri: &'a str,
349 headers: &'a [(&'a str, &'a str)],
350 ) -> Result<Request<&'a mut C>, C::Error> {
351 self.0.initiate_request(method, uri, headers).await?;
352
353 Ok(Request::wrap(&mut self.0))
354 }
355
356 pub fn raw_connection(&mut self) -> Result<&mut C::RawConnection, C::Error> {
357 self.0.raw_connection()
358 }
359 }
360
361 impl<C> ErrorType for Client<C>
362 where
363 C: ErrorType,
364 {
365 type Error = C::Error;
366 }
367
368 #[derive(Debug)]
369 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
370 pub struct Request<C>(C);
371
372 impl<C> Request<C>
373 where
374 C: Connection,
375 {
376 pub fn wrap(connection: C) -> Request<C> {
377 if !connection.is_request_initiated() {
378 panic!("connection is not in request phase");
379 }
380
381 Request(connection)
382 }
383
384 pub async fn submit(mut self) -> Result<Response<C>, C::Error> {
385 self.0.initiate_response().await?;
386
387 Ok(Response(self.0))
388 }
389
390 pub fn connection(&mut self) -> &mut C {
391 &mut self.0
392 }
393
394 pub fn release(self) -> C {
395 self.0
396 }
397
398 pub async fn write(&mut self, buf: &[u8]) -> Result<usize, C::Error> {
399 self.0.write(buf).await
400 }
401
402 pub async fn flush(&mut self) -> Result<(), C::Error> {
403 self.0.flush().await
404 }
405 }
406
407 impl<C> ErrorType for Request<C>
408 where
409 C: ErrorType,
410 {
411 type Error = C::Error;
412 }
413
414 impl<C> Write for Request<C>
415 where
416 C: Connection,
417 {
418 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
419 Request::write(self, buf).await
420 }
421
422 async fn flush(&mut self) -> Result<(), Self::Error> {
423 Request::flush(self).await
424 }
425 }
426
427 #[derive(Debug)]
428 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
429 pub struct Response<C>(C);
430
431 impl<C> Response<C>
432 where
433 C: Connection,
434 {
435 pub fn wrap(connection: C) -> Response<C> {
436 if !connection.is_response_initiated() {
437 panic!("connection is not in response phase");
438 }
439
440 Response(connection)
441 }
442
443 pub fn split(&mut self) -> (&C::Headers, &mut C::Read) {
444 self.0.split()
445 }
446
447 pub fn connection(&mut self) -> &mut C {
448 &mut self.0
449 }
450
451 pub fn release(self) -> C {
452 self.0
453 }
454
455 pub fn status(&self) -> u16 {
456 self.0.status()
457 }
458
459 pub fn status_message(&self) -> Option<&'_ str> {
460 self.0.status_message()
461 }
462
463 pub fn header(&self, name: &str) -> Option<&'_ str> {
464 self.0.header(name)
465 }
466
467 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, C::Error> {
468 self.0.read(buf).await
469 }
470 }
471
472 impl<C> Status for Response<C>
473 where
474 C: Connection,
475 {
476 fn status(&self) -> u16 {
477 Response::status(self)
478 }
479
480 fn status_message(&self) -> Option<&'_ str> {
481 Response::status_message(self)
482 }
483 }
484
485 impl<C> Headers for Response<C>
486 where
487 C: Connection,
488 {
489 fn header(&self, name: &str) -> Option<&'_ str> {
490 Response::header(self, name)
491 }
492 }
493
494 impl<C> ErrorType for Response<C>
495 where
496 C: ErrorType,
497 {
498 type Error = C::Error;
499 }
500
501 impl<C> Read for Response<C>
502 where
503 C: Connection,
504 {
505 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
506 Response::read(self, buf).await
507 }
508 }
509
510 pub trait Connection: Status + Headers + Read + Write {
511 type Headers: Status + Headers;
512
513 type Read: Read<Error = Self::Error>;
514
515 type RawConnectionError: Error;
516
517 type RawConnection: Read<Error = Self::RawConnectionError>
518 + Write<Error = Self::RawConnectionError>;
519
520 async fn initiate_request(
521 &mut self,
522 method: Method,
523 uri: &str,
524 headers: &[(&str, &str)],
525 ) -> Result<(), Self::Error>;
526
527 fn is_request_initiated(&self) -> bool;
528
529 async fn initiate_response(&mut self) -> Result<(), Self::Error>;
530
531 fn is_response_initiated(&self) -> bool;
532
533 fn split(&mut self) -> (&Self::Headers, &mut Self::Read);
534
535 fn raw_connection(&mut self) -> Result<&mut Self::RawConnection, Self::Error>;
536 }
537
538 impl<C> Connection for &mut C
539 where
540 C: Connection,
541 {
542 type Headers = C::Headers;
543
544 type Read = C::Read;
545
546 type RawConnectionError = C::RawConnectionError;
547
548 type RawConnection = C::RawConnection;
549
550 async fn initiate_request(
551 &mut self,
552 method: Method,
553 uri: &str,
554 headers: &[(&str, &str)],
555 ) -> Result<(), Self::Error> {
556 (*self).initiate_request(method, uri, headers).await
557 }
558
559 fn is_request_initiated(&self) -> bool {
560 (**self).is_request_initiated()
561 }
562
563 async fn initiate_response(&mut self) -> Result<(), Self::Error> {
564 (*self).initiate_response().await
565 }
566
567 fn is_response_initiated(&self) -> bool {
568 (**self).is_response_initiated()
569 }
570
571 fn split(&mut self) -> (&Self::Headers, &mut Self::Read) {
572 (*self).split()
573 }
574
575 fn raw_connection(&mut self) -> Result<&mut Self::RawConnection, Self::Error> {
576 (*self).raw_connection()
577 }
578 }
579}