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}