puzz_http/
response.rs

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