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}