puzz_http/request.rs
1use std::fmt;
2
3use crate::{Extensions, HeaderMap, HeaderName, HeaderValue, Method, Result, Uri, Version};
4
5/// 一个HTTP请求。
6///
7/// HTTP请求由头部和可选的正文组成。正文是泛型的,允许任意类型来表示HTTP请求的正文。
8pub struct Request<T> {
9 head: Head,
10 body: T,
11}
12
13/// HTTP请求的头部。
14///
15/// HTTP请求的头部由方法、URI、版本和一组标头组成。
16#[derive(Default)]
17pub struct Head {
18 /// HTTP请求的方法
19 pub method: Method,
20
21 /// HTTP请求的URI
22 pub uri: Uri,
23
24 /// HTTP请求的版本
25 pub version: Version,
26
27 /// HTTP请求的标头集
28 pub headers: HeaderMap<HeaderValue>,
29
30 /// HTTP请求的扩展
31 pub extensions: Extensions,
32
33 _priv: (),
34}
35
36/// HTTP请求的构建器。
37#[derive(Debug)]
38pub struct Builder {
39 inner: Result<Head>,
40}
41
42impl Request<()> {
43 /// 创建新的构建器以构建请求。
44 ///
45 /// # 例子
46 ///
47 /// ```
48 /// use puzz_http::Request;
49 ///
50 /// let request = Request::builder()
51 /// .method("GET")
52 /// .uri("https://www.rust-lang.org/")
53 /// .header("X-Custom-Foo", "Bar")
54 /// .body(())
55 /// .unwrap();
56 /// ```
57 #[inline]
58 pub fn builder() -> Builder {
59 Builder::new()
60 }
61}
62
63impl<T> Request<T> {
64 /// 使用给定的正文创建一个空白的请求。
65 ///
66 /// 此请求的头部将被设置为默认值。
67 ///
68 /// # 例子
69 ///
70 /// ```
71 /// use puzz_http::{Method, Request};
72 ///
73 /// let request = Request::new("hello world");
74 ///
75 /// assert_eq!(*request.method(), Method::GET);
76 /// assert_eq!(*request.body(), "hello world");
77 /// ```
78 #[inline]
79 pub fn new(body: T) -> Request<T> {
80 Request {
81 head: Head::new(),
82 body,
83 }
84 }
85
86 /// 使用给定的头部和正文创建请求。
87 ///
88 /// # 例子
89 ///
90 /// ```
91 /// use puzz_http::{Method, Request};
92 ///
93 /// let request = Request::new("hello world");
94 /// let (mut head, body) = request.into_head();
95 ///
96 /// head.method = Method::POST;
97 /// let request = Request::from_head(head, body);
98 ///
99 /// assert_eq!(request.method(), Method::POST);
100 /// assert_eq!(*request.body(), "hello world");
101 /// ```
102 #[inline]
103 pub fn from_head(head: Head, body: T) -> Request<T> {
104 Request { head, body }
105 }
106
107 /// 获取请求的HTTP方法的引用。
108 ///
109 /// # 例子
110 ///
111 /// ```
112 /// use puzz_http::{Method, Request};
113 ///
114 /// let request: Request<()> = Request::default();
115 ///
116 /// assert_eq!(*request.method(), Method::GET);
117 /// ```
118 #[inline]
119 pub fn method(&self) -> &Method {
120 &self.head.method
121 }
122
123 /// 获取请求的HTTP方法的可变引用。
124 ///
125 /// # 例子
126 ///
127 /// ```
128 /// use puzz_http::{Method, Request};
129 ///
130 /// let mut request: Request<()> = Request::default();
131 /// *request.method_mut() = Method::PUT;
132 ///
133 /// assert_eq!(*request.method(), Method::PUT);
134 /// ```
135 #[inline]
136 pub fn method_mut(&mut self) -> &mut Method {
137 &mut self.head.method
138 }
139
140 /// 获取请求的URI的引用。
141 ///
142 /// # 例子
143 ///
144 /// ```
145 /// use puzz_http::Request;
146 ///
147 /// let request: Request<()> = Request::default();
148 ///
149 /// assert_eq!(*request.uri(), *"/");
150 /// ```
151 #[inline]
152 pub fn uri(&self) -> &Uri {
153 &self.head.uri
154 }
155
156 /// 获取请求的URI的可变引用。
157 ///
158 /// # 例子
159 ///
160 /// ```
161 /// use puzz_http::Request;
162 ///
163 /// let mut request: Request<()> = Request::default();
164 /// *request.uri_mut() = "/hello".parse().unwrap();
165 ///
166 /// assert_eq!(*request.uri(), *"/hello");
167 /// ```
168 #[inline]
169 pub fn uri_mut(&mut self) -> &mut Uri {
170 &mut self.head.uri
171 }
172
173 /// 获取请求的版本的引用。
174 ///
175 /// # 例子
176 ///
177 /// ```
178 /// use puzz_http::{Request, Version};
179 ///
180 /// let request: Request<()> = Request::default();
181 ///
182 /// assert_eq!(request.version(), Version::HTTP_11);
183 /// ```
184 #[inline]
185 pub fn version(&self) -> Version {
186 self.head.version
187 }
188
189 /// 获取请求的版本的可变引用。
190 ///
191 /// # 例子
192 ///
193 /// ```
194 /// use puzz_http::{Request, Version};
195 ///
196 /// let mut request: Request<()> = Request::default();
197 /// *request.version_mut() = Version::HTTP_2;
198 ///
199 /// assert_eq!(request.version(), Version::HTTP_2);
200 /// ```
201 #[inline]
202 pub fn version_mut(&mut self) -> &mut Version {
203 &mut self.head.version
204 }
205
206 /// 获取请求的标头集的引用。
207 ///
208 /// # 例子
209 ///
210 /// ```
211 /// use puzz_http::Request;
212 ///
213 /// let request: Request<()> = Request::default();
214 ///
215 /// assert!(request.headers().is_empty());
216 /// ```
217 #[inline]
218 pub fn headers(&self) -> &HeaderMap<HeaderValue> {
219 &self.head.headers
220 }
221
222 /// 获取请求的标头集的可变引用。
223 ///
224 /// # 例子
225 ///
226 /// ```
227 /// use puzz_http::Request;
228 /// use puzz_http::header::*;
229 ///
230 /// let mut request: Request<()> = Request::default();
231 /// request.headers_mut().insert(HOST, HeaderValue::from_static("world"));
232 ///
233 /// assert!(!request.headers().is_empty());
234 /// ```
235 #[inline]
236 pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
237 &mut self.head.headers
238 }
239
240 /// 获取请求的扩展的引用。
241 ///
242 /// # 例子
243 ///
244 /// ```
245 /// use puzz_http::Request;
246 ///
247 /// let request: Request<()> = Request::default();
248 ///
249 /// assert!(request.extensions().get::<i32>().is_none());
250 /// ```
251 #[inline]
252 pub fn extensions(&self) -> &Extensions {
253 &self.head.extensions
254 }
255
256 /// 获取请求的扩展的可变引用。
257 ///
258 /// # 例子
259 ///
260 /// ```
261 /// use puzz_http::Request;
262 ///
263 /// let mut request: Request<()> = Request::default();
264 /// request.extensions_mut().insert("hello");
265 ///
266 /// assert_eq!(request.extensions().get(), Some(&"hello"));
267 /// ```
268 #[inline]
269 pub fn extensions_mut(&mut self) -> &mut Extensions {
270 &mut self.head.extensions
271 }
272
273 /// 获取请求的正文的引用。
274 ///
275 /// # 例子
276 ///
277 /// ```
278 /// use puzz_http::Request;
279 ///
280 /// let request: Request<String> = Request::default();
281 ///
282 /// assert!(request.body().is_empty());
283 /// ```
284 #[inline]
285 pub fn body(&self) -> &T {
286 &self.body
287 }
288
289 /// 获取请求的正文的可变引用。
290 ///
291 /// # 例子
292 ///
293 /// ```
294 /// use puzz_http::Request;
295 ///
296 /// let mut request: Request<String> = Request::default();
297 /// request.body_mut().push_str("hello world");
298 ///
299 /// assert!(!request.body().is_empty());
300 /// ```
301 #[inline]
302 pub fn body_mut(&mut self) -> &mut T {
303 &mut self.body
304 }
305
306 /// 消耗请求,只返回请求的正文。
307 ///
308 /// # 例子
309 ///
310 /// ```
311 /// use puzz_http::Request;
312 ///
313 /// let request = Request::new(10);
314 /// let body = request.into_body();
315 ///
316 /// assert_eq!(body, 10);
317 /// ```
318 #[inline]
319 pub fn into_body(self) -> T {
320 self.body
321 }
322
323 /// 消耗请求,返回请求的头部和正文。
324 ///
325 /// # 例子
326 ///
327 /// ```
328 /// use puzz_http::{Method, Request};
329 ///
330 /// let request = Request::new(());
331 /// let (head, body) = request.into_head();
332 ///
333 /// assert_eq!(head.method, Method::GET);
334 /// ```
335 #[inline]
336 pub fn into_head(self) -> (Head, T) {
337 (self.head, self.body)
338 }
339
340 /// 消耗请求,返回带有给定正文的新请求,其正文为传入函数的返回值。
341 ///
342 /// # 例子
343 ///
344 /// ```
345 /// use puzz_http::Request;
346 ///
347 /// let request = Request::builder().body("some string").unwrap();
348 /// let mapped_request: Request<&[u8]> = request.map(|b| {
349 /// assert_eq!(b, "some string");
350 /// b.as_bytes()
351 /// });
352 /// assert_eq!(mapped_request.body(), &"some string".as_bytes());
353 /// ```
354 #[inline]
355 pub fn map<F, U>(self, f: F) -> Request<U>
356 where
357 F: FnOnce(T) -> U,
358 {
359 Request {
360 body: f(self.body),
361 head: self.head,
362 }
363 }
364}
365
366impl<T: Default> Default for Request<T> {
367 fn default() -> Request<T> {
368 Request::new(T::default())
369 }
370}
371
372impl<T: fmt::Debug> fmt::Debug for Request<T> {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 f.debug_struct("Request")
375 .field("method", self.method())
376 .field("uri", self.uri())
377 .field("version", &self.version())
378 .field("headers", self.headers())
379 .field("body", self.body())
380 .finish()
381 }
382}
383
384impl Head {
385 fn new() -> Head {
386 Head::default()
387 }
388}
389
390impl fmt::Debug for Head {
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 f.debug_struct("Head")
393 .field("method", &self.method)
394 .field("uri", &self.uri)
395 .field("version", &self.version)
396 .field("headers", &self.headers)
397 .finish()
398 }
399}
400
401impl Builder {
402 /// 创建构建器的默认实例以构建请求。
403 ///
404 /// # 例子
405 ///
406 /// ```
407 /// use puzz_http::request::Builder;
408 ///
409 /// let req = Builder::new()
410 /// .method("POST")
411 /// .body(())
412 /// .unwrap();
413 /// ```
414 #[inline]
415 pub fn new() -> Builder {
416 Builder::default()
417 }
418
419 /// 设置请求的HTTP方法。
420 ///
421 /// 默认情况下,这是`GET`。
422 ///
423 /// # 例子
424 ///
425 /// ```
426 /// use puzz_http::Request;
427 ///
428 /// let req = Request::builder()
429 /// .method("POST")
430 /// .body(())
431 /// .unwrap();
432 /// ```
433 pub fn method<T>(self, method: T) -> Builder
434 where
435 Method: TryFrom<T>,
436 <Method as TryFrom<T>>::Error: Into<crate::Error>,
437 {
438 self.and_then(move |mut head| {
439 let method = TryFrom::try_from(method).map_err(Into::into)?;
440 head.method = method;
441 Ok(head)
442 })
443 }
444
445 /// 获取请求的HTTP方法。
446 ///
447 /// 默认情况下,这是`GET`。如果构建器有错误,则返回[`None`]。
448 ///
449 /// # 例子
450 ///
451 /// ```
452 /// use puzz_http::{Method, Request};
453 ///
454 /// let mut req = Request::builder();
455 /// assert_eq!(req.method_ref(), Some(&Method::GET));
456 ///
457 /// req = req.method("POST");
458 /// assert_eq!(req.method_ref(), Some(&Method::POST));
459 /// ```
460 pub fn method_ref(&self) -> Option<&Method> {
461 self.inner.as_ref().ok().map(|h| &h.method)
462 }
463
464 /// 设置请求的URI。
465 ///
466 /// 默认情况下,这是`/`。
467 ///
468 /// # 例子
469 ///
470 /// ```
471 /// use puzz_http::Request;
472 ///
473 /// let req = Request::builder()
474 /// .uri("https://www.rust-lang.org/")
475 /// .body(())
476 /// .unwrap();
477 /// ```
478 pub fn uri<T>(self, uri: T) -> Builder
479 where
480 Uri: TryFrom<T>,
481 <Uri as TryFrom<T>>::Error: Into<crate::Error>,
482 {
483 self.and_then(move |mut head| {
484 head.uri = TryFrom::try_from(uri).map_err(Into::into)?;
485 Ok(head)
486 })
487 }
488
489 /// 获取请求的URI。
490 ///
491 /// 默认情况下,这是`/`。如果构建器有错误,则返回[`None`]。
492 ///
493 /// # 例子
494 ///
495 /// ```
496 /// use puzz_http::Request;
497 ///
498 /// let mut req = Request::builder();
499 /// assert_eq!(req.uri_ref().unwrap(), "/");
500 ///
501 /// req = req.uri("https://www.rust-lang.org/");
502 /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/");
503 /// ```
504 pub fn uri_ref(&self) -> Option<&Uri> {
505 self.inner.as_ref().ok().map(|h| &h.uri)
506 }
507
508 /// 设置请求的HTTP版本。
509 ///
510 /// 默认情况下,这是`HTTP/1.1`。
511 ///
512 /// # 例子
513 ///
514 /// ```
515 /// use puzz_http::{Request, Version};
516 ///
517 /// let req = Request::builder()
518 /// .version(Version::HTTP_2)
519 /// .body(())
520 /// .unwrap();
521 /// ```
522 pub fn version(self, version: Version) -> Builder {
523 self.and_then(move |mut head| {
524 head.version = version;
525 Ok(head)
526 })
527 }
528
529 /// 获取请求的HTTP版本。
530 ///
531 /// 默认情况下,这是`HTTP/1.1`。如果构建器有错误,则返回[`None`]。
532 ///
533 /// # 例子
534 ///
535 /// ```
536 /// use puzz_http::{Request, Version};
537 ///
538 /// let mut req = Request::builder();
539 /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_11);
540 ///
541 /// req = req.version(Version::HTTP_2);
542 /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_2);
543 /// ```
544 pub fn version_ref(&self) -> Option<&Version> {
545 self.inner.as_ref().ok().map(|h| &h.version)
546 }
547
548 /// 将标头追加到请求中。
549 ///
550 /// 此函数将提供的键值对追加到请求内部的[`HeaderMap`]中。本质上,
551 /// 这相当于调用[`HeaderMap::append`]。
552 ///
553 /// # 例子
554 ///
555 /// ```
556 /// use puzz_http::Request;
557 ///
558 /// let req = Request::builder()
559 /// .header("Accept", "text/html")
560 /// .header("X-Custom-Foo", "bar")
561 /// .body(())
562 /// .unwrap();
563 /// ```
564 pub fn header<K, V>(self, key: K, value: V) -> Builder
565 where
566 HeaderName: TryFrom<K>,
567 <HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
568 HeaderValue: TryFrom<V>,
569 <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
570 {
571 self.and_then(move |mut head| {
572 let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
573 let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
574 head.headers.append(name, value);
575 Ok(head)
576 })
577 }
578
579 /// 获取请求的标头集的引用。
580 ///
581 /// 如果构建器有错误,则返回[`None`]。
582 ///
583 /// # 例子
584 ///
585 /// ```
586 /// use puzz_http::Request;
587 ///
588 /// let req = Request::builder()
589 /// .header("Accept", "text/html")
590 /// .header("X-Custom-Foo", "bar");
591 ///
592 /// let headers = req.headers_ref().unwrap();
593 ///
594 /// assert_eq!( headers["Accept"], "text/html" );
595 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
596 /// ```
597 pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
598 self.inner.as_ref().ok().map(|h| &h.headers)
599 }
600
601 /// 获取请求的标头集的可变引用。
602 ///
603 /// 如果构建器有错误,则返回[`None`]。
604 ///
605 /// # 例子
606 ///
607 /// ```
608 /// use puzz_http::{HeaderValue, Request};
609 ///
610 /// let mut req = Request::builder();
611 ///
612 /// let headers = req.headers_mut().unwrap();
613 /// headers.insert("Accept", HeaderValue::from_static("text/html"));
614 /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
615 ///
616 /// let headers = req.headers_ref().unwrap();
617 /// assert_eq!( headers["Accept"], "text/html" );
618 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
619 /// ```
620 pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
621 self.inner.as_mut().ok().map(|h| &mut h.headers)
622 }
623
624 /// 将一个类型添加到请求的扩展中。
625 ///
626 /// # 例子
627 ///
628 /// ```
629 /// use puzz_http::Request;
630 ///
631 /// let req = Request::builder()
632 /// .extension("My Extension")
633 /// .body(())
634 /// .unwrap();
635 ///
636 /// assert_eq!(req.extensions().get::<&'static str>(),
637 /// Some(&"My Extension"));
638 /// ```
639 pub fn extension<T: 'static>(self, extension: T) -> Builder {
640 self.and_then(move |mut head| {
641 head.extensions.insert(extension);
642 Ok(head)
643 })
644 }
645
646 /// 获取请求的扩展的引用。
647 ///
648 /// 如果构建器有错误,则返回[`None`]。
649 ///
650 /// # 例子
651 ///
652 /// ```
653 /// use puzz_http::Request;
654 ///
655 /// let req = Request::builder().extension("My Extension").extension(5u32);
656 /// let extensions = req.extensions_ref().unwrap();
657 ///
658 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
659 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
660 /// ```
661 pub fn extensions_ref(&self) -> Option<&Extensions> {
662 self.inner.as_ref().ok().map(|h| &h.extensions)
663 }
664
665 /// 获取请求的扩展的可变引用。
666 ///
667 /// 如果构建器有错误,则返回[`None`]。
668 ///
669 /// # 例子
670 ///
671 /// ```
672 /// use puzz_http::Request;
673 ///
674 /// let mut req = Request::builder().extension("My Extension");
675 /// let mut extensions = req.extensions_mut().unwrap();
676 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
677 ///
678 /// extensions.insert(5u32);
679 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
680 /// ```
681 pub fn extensions_mut(&mut self) -> Option<&mut Extensions> {
682 self.inner.as_mut().ok().map(|h| &mut h.extensions)
683 }
684
685 /// 消耗构建器,使用给定的正文构建请求。
686 ///
687 /// # 错误
688 ///
689 /// 如果之前配置的任意一个参数发生错误,则在调用此函数时将错误返回。
690 ///
691 /// # 例子
692 ///
693 /// ```
694 /// use puzz_http::Request;
695 ///
696 /// let request = Request::builder()
697 /// .body(())
698 /// .unwrap();
699 /// ```
700 pub fn body<T>(self, body: T) -> Result<Request<T>> {
701 self.inner.map(move |head| Request { head, body })
702 }
703
704 fn and_then<F>(self, func: F) -> Self
705 where
706 F: FnOnce(Head) -> Result<Head>,
707 {
708 Builder {
709 inner: self.inner.and_then(func),
710 }
711 }
712}
713
714impl Default for Builder {
715 #[inline]
716 fn default() -> Builder {
717 Builder {
718 inner: Ok(Head::new()),
719 }
720 }
721}