1 | //! HTTP response types. |
2 | //! |
3 | //! This module contains structs related to HTTP responses, notably the |
4 | //! `Response` type itself as well as a builder to create responses. Typically |
5 | //! you'll import the `http::Response` type rather than reaching into this |
6 | //! module itself. |
7 | //! |
8 | //! # Examples |
9 | //! |
10 | //! Creating a `Response` to return |
11 | //! |
12 | //! ``` |
13 | //! use http::{Request, Response, StatusCode}; |
14 | //! |
15 | //! fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
16 | //! let mut builder = Response::builder() |
17 | //! .header("Foo" , "Bar" ) |
18 | //! .status(StatusCode::OK); |
19 | //! |
20 | //! if req.headers().contains_key("Another-Header" ) { |
21 | //! builder = builder.header("Another-Header" , "Ack" ); |
22 | //! } |
23 | //! |
24 | //! builder.body(()) |
25 | //! } |
26 | //! ``` |
27 | //! |
28 | //! A simple 404 handler |
29 | //! |
30 | //! ``` |
31 | //! use http::{Request, Response, StatusCode}; |
32 | //! |
33 | //! fn not_found(_req: Request<()>) -> http::Result<Response<()>> { |
34 | //! Response::builder() |
35 | //! .status(StatusCode::NOT_FOUND) |
36 | //! .body(()) |
37 | //! } |
38 | //! ``` |
39 | //! |
40 | //! Or otherwise inspecting the result of a request: |
41 | //! |
42 | //! ```no_run |
43 | //! use http::{Request, Response}; |
44 | //! |
45 | //! fn get(url: &str) -> http::Result<Response<()>> { |
46 | //! // ... |
47 | //! # panic!() |
48 | //! } |
49 | //! |
50 | //! let response = get("https://www.rust-lang.org/" ).unwrap(); |
51 | //! |
52 | //! if !response.status().is_success() { |
53 | //! panic!("failed to get a successful response status!" ); |
54 | //! } |
55 | //! |
56 | //! if let Some(date) = response.headers().get("Date" ) { |
57 | //! // we've got a `Date` header! |
58 | //! } |
59 | //! |
60 | //! let body = response.body(); |
61 | //! // ... |
62 | //! ``` |
63 | |
64 | use std::any::Any; |
65 | use std::convert::TryFrom; |
66 | use std::fmt; |
67 | |
68 | use crate::header::{HeaderMap, HeaderName, HeaderValue}; |
69 | use crate::status::StatusCode; |
70 | use crate::version::Version; |
71 | use crate::{Extensions, Result}; |
72 | |
73 | /// Represents an HTTP response |
74 | /// |
75 | /// An HTTP response consists of a head and a potentially optional body. The body |
76 | /// component is generic, enabling arbitrary types to represent the HTTP body. |
77 | /// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a |
78 | /// value that has been deserialized. |
79 | /// |
80 | /// Typically you'll work with responses on the client side as the result of |
81 | /// sending a `Request` and on the server you'll be generating a `Response` to |
82 | /// send back to the client. |
83 | /// |
84 | /// # Examples |
85 | /// |
86 | /// Creating a `Response` to return |
87 | /// |
88 | /// ``` |
89 | /// use http::{Request, Response, StatusCode}; |
90 | /// |
91 | /// fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
92 | /// let mut builder = Response::builder() |
93 | /// .header("Foo" , "Bar" ) |
94 | /// .status(StatusCode::OK); |
95 | /// |
96 | /// if req.headers().contains_key("Another-Header" ) { |
97 | /// builder = builder.header("Another-Header" , "Ack" ); |
98 | /// } |
99 | /// |
100 | /// builder.body(()) |
101 | /// } |
102 | /// ``` |
103 | /// |
104 | /// A simple 404 handler |
105 | /// |
106 | /// ``` |
107 | /// use http::{Request, Response, StatusCode}; |
108 | /// |
109 | /// fn not_found(_req: Request<()>) -> http::Result<Response<()>> { |
110 | /// Response::builder() |
111 | /// .status(StatusCode::NOT_FOUND) |
112 | /// .body(()) |
113 | /// } |
114 | /// ``` |
115 | /// |
116 | /// Or otherwise inspecting the result of a request: |
117 | /// |
118 | /// ```no_run |
119 | /// use http::{Request, Response}; |
120 | /// |
121 | /// fn get(url: &str) -> http::Result<Response<()>> { |
122 | /// // ... |
123 | /// # panic!() |
124 | /// } |
125 | /// |
126 | /// let response = get("https://www.rust-lang.org/" ).unwrap(); |
127 | /// |
128 | /// if !response.status().is_success() { |
129 | /// panic!("failed to get a successful response status!" ); |
130 | /// } |
131 | /// |
132 | /// if let Some(date) = response.headers().get("Date" ) { |
133 | /// // we've got a `Date` header! |
134 | /// } |
135 | /// |
136 | /// let body = response.body(); |
137 | /// // ... |
138 | /// ``` |
139 | /// |
140 | /// Deserialize a response of bytes via json: |
141 | /// |
142 | /// ``` |
143 | /// # extern crate serde; |
144 | /// # extern crate serde_json; |
145 | /// # extern crate http; |
146 | /// use http::Response; |
147 | /// use serde::de; |
148 | /// |
149 | /// fn deserialize<T>(res: Response<Vec<u8>>) -> serde_json::Result<Response<T>> |
150 | /// where for<'de> T: de::Deserialize<'de>, |
151 | /// { |
152 | /// let (parts, body) = res.into_parts(); |
153 | /// let body = serde_json::from_slice(&body)?; |
154 | /// Ok(Response::from_parts(parts, body)) |
155 | /// } |
156 | /// # |
157 | /// # fn main() {} |
158 | /// ``` |
159 | /// |
160 | /// Or alternatively, serialize the body of a response to json |
161 | /// |
162 | /// ``` |
163 | /// # extern crate serde; |
164 | /// # extern crate serde_json; |
165 | /// # extern crate http; |
166 | /// use http::Response; |
167 | /// use serde::ser; |
168 | /// |
169 | /// fn serialize<T>(res: Response<T>) -> serde_json::Result<Response<Vec<u8>>> |
170 | /// where T: ser::Serialize, |
171 | /// { |
172 | /// let (parts, body) = res.into_parts(); |
173 | /// let body = serde_json::to_vec(&body)?; |
174 | /// Ok(Response::from_parts(parts, body)) |
175 | /// } |
176 | /// # |
177 | /// # fn main() {} |
178 | /// ``` |
179 | pub struct Response<T> { |
180 | head: Parts, |
181 | body: T, |
182 | } |
183 | |
184 | /// Component parts of an HTTP `Response` |
185 | /// |
186 | /// The HTTP response head consists of a status, version, and a set of |
187 | /// header fields. |
188 | pub struct Parts { |
189 | /// The response's status |
190 | pub status: StatusCode, |
191 | |
192 | /// The response's version |
193 | pub version: Version, |
194 | |
195 | /// The response's headers |
196 | pub headers: HeaderMap<HeaderValue>, |
197 | |
198 | /// The response's extensions |
199 | pub extensions: Extensions, |
200 | |
201 | _priv: (), |
202 | } |
203 | |
204 | /// An HTTP response builder |
205 | /// |
206 | /// This type can be used to construct an instance of `Response` through a |
207 | /// builder-like pattern. |
208 | #[derive (Debug)] |
209 | pub struct Builder { |
210 | inner: Result<Parts>, |
211 | } |
212 | |
213 | impl Response<()> { |
214 | /// Creates a new builder-style object to manufacture a `Response` |
215 | /// |
216 | /// This method returns an instance of `Builder` which can be used to |
217 | /// create a `Response`. |
218 | /// |
219 | /// # Examples |
220 | /// |
221 | /// ``` |
222 | /// # use http::*; |
223 | /// let response = Response::builder() |
224 | /// .status(200) |
225 | /// .header("X-Custom-Foo" , "Bar" ) |
226 | /// .body(()) |
227 | /// .unwrap(); |
228 | /// ``` |
229 | #[inline ] |
230 | pub fn builder() -> Builder { |
231 | Builder::new() |
232 | } |
233 | } |
234 | |
235 | impl<T> Response<T> { |
236 | /// Creates a new blank `Response` with the body |
237 | /// |
238 | /// The component ports of this response will be set to their default, e.g. |
239 | /// the ok status, no headers, etc. |
240 | /// |
241 | /// # Examples |
242 | /// |
243 | /// ``` |
244 | /// # use http::*; |
245 | /// let response = Response::new("hello world" ); |
246 | /// |
247 | /// assert_eq!(response.status(), StatusCode::OK); |
248 | /// assert_eq!(*response.body(), "hello world" ); |
249 | /// ``` |
250 | #[inline ] |
251 | pub fn new(body: T) -> Response<T> { |
252 | Response { |
253 | head: Parts::new(), |
254 | body: body, |
255 | } |
256 | } |
257 | |
258 | /// Creates a new `Response` with the given head and body |
259 | /// |
260 | /// # Examples |
261 | /// |
262 | /// ``` |
263 | /// # use http::*; |
264 | /// let response = Response::new("hello world" ); |
265 | /// let (mut parts, body) = response.into_parts(); |
266 | /// |
267 | /// parts.status = StatusCode::BAD_REQUEST; |
268 | /// let response = Response::from_parts(parts, body); |
269 | /// |
270 | /// assert_eq!(response.status(), StatusCode::BAD_REQUEST); |
271 | /// assert_eq!(*response.body(), "hello world" ); |
272 | /// ``` |
273 | #[inline ] |
274 | pub fn from_parts(parts: Parts, body: T) -> Response<T> { |
275 | Response { |
276 | head: parts, |
277 | body: body, |
278 | } |
279 | } |
280 | |
281 | /// Returns the `StatusCode`. |
282 | /// |
283 | /// # Examples |
284 | /// |
285 | /// ``` |
286 | /// # use http::*; |
287 | /// let response: Response<()> = Response::default(); |
288 | /// assert_eq!(response.status(), StatusCode::OK); |
289 | /// ``` |
290 | #[inline ] |
291 | pub fn status(&self) -> StatusCode { |
292 | self.head.status |
293 | } |
294 | |
295 | /// Returns a mutable reference to the associated `StatusCode`. |
296 | /// |
297 | /// # Examples |
298 | /// |
299 | /// ``` |
300 | /// # use http::*; |
301 | /// let mut response: Response<()> = Response::default(); |
302 | /// *response.status_mut() = StatusCode::CREATED; |
303 | /// assert_eq!(response.status(), StatusCode::CREATED); |
304 | /// ``` |
305 | #[inline ] |
306 | pub fn status_mut(&mut self) -> &mut StatusCode { |
307 | &mut self.head.status |
308 | } |
309 | |
310 | /// Returns a reference to the associated version. |
311 | /// |
312 | /// # Examples |
313 | /// |
314 | /// ``` |
315 | /// # use http::*; |
316 | /// let response: Response<()> = Response::default(); |
317 | /// assert_eq!(response.version(), Version::HTTP_11); |
318 | /// ``` |
319 | #[inline ] |
320 | pub fn version(&self) -> Version { |
321 | self.head.version |
322 | } |
323 | |
324 | /// Returns a mutable reference to the associated version. |
325 | /// |
326 | /// # Examples |
327 | /// |
328 | /// ``` |
329 | /// # use http::*; |
330 | /// let mut response: Response<()> = Response::default(); |
331 | /// *response.version_mut() = Version::HTTP_2; |
332 | /// assert_eq!(response.version(), Version::HTTP_2); |
333 | /// ``` |
334 | #[inline ] |
335 | pub fn version_mut(&mut self) -> &mut Version { |
336 | &mut self.head.version |
337 | } |
338 | |
339 | /// Returns a reference to the associated header field map. |
340 | /// |
341 | /// # Examples |
342 | /// |
343 | /// ``` |
344 | /// # use http::*; |
345 | /// let response: Response<()> = Response::default(); |
346 | /// assert!(response.headers().is_empty()); |
347 | /// ``` |
348 | #[inline ] |
349 | pub fn headers(&self) -> &HeaderMap<HeaderValue> { |
350 | &self.head.headers |
351 | } |
352 | |
353 | /// Returns a mutable reference to the associated header field map. |
354 | /// |
355 | /// # Examples |
356 | /// |
357 | /// ``` |
358 | /// # use http::*; |
359 | /// # use http::header::*; |
360 | /// let mut response: Response<()> = Response::default(); |
361 | /// response.headers_mut().insert(HOST, HeaderValue::from_static("world" )); |
362 | /// assert!(!response.headers().is_empty()); |
363 | /// ``` |
364 | #[inline ] |
365 | pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> { |
366 | &mut self.head.headers |
367 | } |
368 | |
369 | /// Returns a reference to the associated extensions. |
370 | /// |
371 | /// # Examples |
372 | /// |
373 | /// ``` |
374 | /// # use http::*; |
375 | /// let response: Response<()> = Response::default(); |
376 | /// assert!(response.extensions().get::<i32>().is_none()); |
377 | /// ``` |
378 | #[inline ] |
379 | pub fn extensions(&self) -> &Extensions { |
380 | &self.head.extensions |
381 | } |
382 | |
383 | /// Returns a mutable reference to the associated extensions. |
384 | /// |
385 | /// # Examples |
386 | /// |
387 | /// ``` |
388 | /// # use http::*; |
389 | /// # use http::header::*; |
390 | /// let mut response: Response<()> = Response::default(); |
391 | /// response.extensions_mut().insert("hello" ); |
392 | /// assert_eq!(response.extensions().get(), Some(&"hello" )); |
393 | /// ``` |
394 | #[inline ] |
395 | pub fn extensions_mut(&mut self) -> &mut Extensions { |
396 | &mut self.head.extensions |
397 | } |
398 | |
399 | /// Returns a reference to the associated HTTP body. |
400 | /// |
401 | /// # Examples |
402 | /// |
403 | /// ``` |
404 | /// # use http::*; |
405 | /// let response: Response<String> = Response::default(); |
406 | /// assert!(response.body().is_empty()); |
407 | /// ``` |
408 | #[inline ] |
409 | pub fn body(&self) -> &T { |
410 | &self.body |
411 | } |
412 | |
413 | /// Returns a mutable reference to the associated HTTP body. |
414 | /// |
415 | /// # Examples |
416 | /// |
417 | /// ``` |
418 | /// # use http::*; |
419 | /// let mut response: Response<String> = Response::default(); |
420 | /// response.body_mut().push_str("hello world" ); |
421 | /// assert!(!response.body().is_empty()); |
422 | /// ``` |
423 | #[inline ] |
424 | pub fn body_mut(&mut self) -> &mut T { |
425 | &mut self.body |
426 | } |
427 | |
428 | /// Consumes the response, returning just the body. |
429 | /// |
430 | /// # Examples |
431 | /// |
432 | /// ``` |
433 | /// # use http::Response; |
434 | /// let response = Response::new(10); |
435 | /// let body = response.into_body(); |
436 | /// assert_eq!(body, 10); |
437 | /// ``` |
438 | #[inline ] |
439 | pub fn into_body(self) -> T { |
440 | self.body |
441 | } |
442 | |
443 | /// Consumes the response returning the head and body parts. |
444 | /// |
445 | /// # Examples |
446 | /// |
447 | /// ``` |
448 | /// # use http::*; |
449 | /// let response: Response<()> = Response::default(); |
450 | /// let (parts, body) = response.into_parts(); |
451 | /// assert_eq!(parts.status, StatusCode::OK); |
452 | /// ``` |
453 | #[inline ] |
454 | pub fn into_parts(self) -> (Parts, T) { |
455 | (self.head, self.body) |
456 | } |
457 | |
458 | /// Consumes the response returning a new response with body mapped to the |
459 | /// return type of the passed in function. |
460 | /// |
461 | /// # Examples |
462 | /// |
463 | /// ``` |
464 | /// # use http::*; |
465 | /// let response = Response::builder().body("some string" ).unwrap(); |
466 | /// let mapped_response: Response<&[u8]> = response.map(|b| { |
467 | /// assert_eq!(b, "some string" ); |
468 | /// b.as_bytes() |
469 | /// }); |
470 | /// assert_eq!(mapped_response.body(), &"some string" .as_bytes()); |
471 | /// ``` |
472 | #[inline ] |
473 | pub fn map<F, U>(self, f: F) -> Response<U> |
474 | where |
475 | F: FnOnce(T) -> U, |
476 | { |
477 | Response { |
478 | body: f(self.body), |
479 | head: self.head, |
480 | } |
481 | } |
482 | } |
483 | |
484 | impl<T: Default> Default for Response<T> { |
485 | #[inline ] |
486 | fn default() -> Response<T> { |
487 | Response::new(T::default()) |
488 | } |
489 | } |
490 | |
491 | impl<T: fmt::Debug> fmt::Debug for Response<T> { |
492 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
493 | f&mut DebugStruct<'_, '_>.debug_struct("Response" ) |
494 | .field("status" , &self.status()) |
495 | .field("version" , &self.version()) |
496 | .field("headers" , self.headers()) |
497 | // omits Extensions because not useful |
498 | .field(name:"body" , self.body()) |
499 | .finish() |
500 | } |
501 | } |
502 | |
503 | impl Parts { |
504 | /// Creates a new default instance of `Parts` |
505 | fn new() -> Parts { |
506 | Parts { |
507 | status: StatusCode::default(), |
508 | version: Version::default(), |
509 | headers: HeaderMap::default(), |
510 | extensions: Extensions::default(), |
511 | _priv: (), |
512 | } |
513 | } |
514 | } |
515 | |
516 | impl fmt::Debug for Parts { |
517 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
518 | f&mut DebugStruct<'_, '_>.debug_struct("Parts" ) |
519 | .field("status" , &self.status) |
520 | .field("version" , &self.version) |
521 | .field(name:"headers" , &self.headers) |
522 | // omits Extensions because not useful |
523 | // omits _priv because not useful |
524 | .finish() |
525 | } |
526 | } |
527 | |
528 | impl Builder { |
529 | /// Creates a new default instance of `Builder` to construct either a |
530 | /// `Head` or a `Response`. |
531 | /// |
532 | /// # Examples |
533 | /// |
534 | /// ``` |
535 | /// # use http::*; |
536 | /// |
537 | /// let response = response::Builder::new() |
538 | /// .status(200) |
539 | /// .body(()) |
540 | /// .unwrap(); |
541 | /// ``` |
542 | #[inline ] |
543 | pub fn new() -> Builder { |
544 | Builder::default() |
545 | } |
546 | |
547 | /// Set the HTTP status for this response. |
548 | /// |
549 | /// By default this is `200`. |
550 | /// |
551 | /// # Examples |
552 | /// |
553 | /// ``` |
554 | /// # use http::*; |
555 | /// |
556 | /// let response = Response::builder() |
557 | /// .status(200) |
558 | /// .body(()) |
559 | /// .unwrap(); |
560 | /// ``` |
561 | pub fn status<T>(self, status: T) -> Builder |
562 | where |
563 | StatusCode: TryFrom<T>, |
564 | <StatusCode as TryFrom<T>>::Error: Into<crate::Error>, |
565 | { |
566 | self.and_then(move |mut head| { |
567 | head.status = TryFrom::try_from(status).map_err(Into::into)?; |
568 | Ok(head) |
569 | }) |
570 | } |
571 | |
572 | /// Set the HTTP version for this response. |
573 | /// |
574 | /// By default this is HTTP/1.1 |
575 | /// |
576 | /// # Examples |
577 | /// |
578 | /// ``` |
579 | /// # use http::*; |
580 | /// |
581 | /// let response = Response::builder() |
582 | /// .version(Version::HTTP_2) |
583 | /// .body(()) |
584 | /// .unwrap(); |
585 | /// ``` |
586 | pub fn version(self, version: Version) -> Builder { |
587 | self.and_then(move |mut head| { |
588 | head.version = version; |
589 | Ok(head) |
590 | }) |
591 | } |
592 | |
593 | /// Appends a header to this response builder. |
594 | /// |
595 | /// This function will append the provided key/value as a header to the |
596 | /// internal `HeaderMap` being constructed. Essentially this is equivalent |
597 | /// to calling `HeaderMap::append`. |
598 | /// |
599 | /// # Examples |
600 | /// |
601 | /// ``` |
602 | /// # use http::*; |
603 | /// # use http::header::HeaderValue; |
604 | /// |
605 | /// let response = Response::builder() |
606 | /// .header("Content-Type" , "text/html" ) |
607 | /// .header("X-Custom-Foo" , "bar" ) |
608 | /// .header("content-length" , 0) |
609 | /// .body(()) |
610 | /// .unwrap(); |
611 | /// ``` |
612 | pub fn header<K, V>(self, key: K, value: V) -> Builder |
613 | where |
614 | HeaderName: TryFrom<K>, |
615 | <HeaderName as TryFrom<K>>::Error: Into<crate::Error>, |
616 | HeaderValue: TryFrom<V>, |
617 | <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>, |
618 | { |
619 | self.and_then(move |mut head| { |
620 | let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?; |
621 | let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?; |
622 | head.headers.try_append(name, value)?; |
623 | Ok(head) |
624 | }) |
625 | } |
626 | |
627 | /// Get header on this response builder. |
628 | /// |
629 | /// When builder has error returns None. |
630 | /// |
631 | /// # Example |
632 | /// |
633 | /// ``` |
634 | /// # use http::Response; |
635 | /// # use http::header::HeaderValue; |
636 | /// let res = Response::builder() |
637 | /// .header("Accept" , "text/html" ) |
638 | /// .header("X-Custom-Foo" , "bar" ); |
639 | /// let headers = res.headers_ref().unwrap(); |
640 | /// assert_eq!( headers["Accept" ], "text/html" ); |
641 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
642 | /// ``` |
643 | pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> { |
644 | self.inner.as_ref().ok().map(|h| &h.headers) |
645 | } |
646 | |
647 | /// Get header on this response builder. |
648 | /// when builder has error returns None |
649 | /// |
650 | /// # Example |
651 | /// |
652 | /// ``` |
653 | /// # use http::*; |
654 | /// # use http::header::HeaderValue; |
655 | /// # use http::response::Builder; |
656 | /// let mut res = Response::builder(); |
657 | /// { |
658 | /// let headers = res.headers_mut().unwrap(); |
659 | /// headers.insert("Accept" , HeaderValue::from_static("text/html" )); |
660 | /// headers.insert("X-Custom-Foo" , HeaderValue::from_static("bar" )); |
661 | /// } |
662 | /// let headers = res.headers_ref().unwrap(); |
663 | /// assert_eq!( headers["Accept" ], "text/html" ); |
664 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
665 | /// ``` |
666 | pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> { |
667 | self.inner.as_mut().ok().map(|h| &mut h.headers) |
668 | } |
669 | |
670 | /// Adds an extension to this builder |
671 | /// |
672 | /// # Examples |
673 | /// |
674 | /// ``` |
675 | /// # use http::*; |
676 | /// |
677 | /// let response = Response::builder() |
678 | /// .extension("My Extension" ) |
679 | /// .body(()) |
680 | /// .unwrap(); |
681 | /// |
682 | /// assert_eq!(response.extensions().get::<&'static str>(), |
683 | /// Some(&"My Extension" )); |
684 | /// ``` |
685 | pub fn extension<T>(self, extension: T) -> Builder |
686 | where |
687 | T: Any + Send + Sync + 'static, |
688 | { |
689 | self.and_then(move |mut head| { |
690 | head.extensions.insert(extension); |
691 | Ok(head) |
692 | }) |
693 | } |
694 | |
695 | /// Get a reference to the extensions for this response builder. |
696 | /// |
697 | /// If the builder has an error, this returns `None`. |
698 | /// |
699 | /// # Example |
700 | /// |
701 | /// ``` |
702 | /// # use http::Response; |
703 | /// let res = Response::builder().extension("My Extension" ).extension(5u32); |
704 | /// let extensions = res.extensions_ref().unwrap(); |
705 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
706 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
707 | /// ``` |
708 | pub fn extensions_ref(&self) -> Option<&Extensions> { |
709 | self.inner.as_ref().ok().map(|h| &h.extensions) |
710 | } |
711 | |
712 | /// Get a mutable reference to the extensions for this response builder. |
713 | /// |
714 | /// If the builder has an error, this returns `None`. |
715 | /// |
716 | /// # Example |
717 | /// |
718 | /// ``` |
719 | /// # use http::Response; |
720 | /// let mut res = Response::builder().extension("My Extension" ); |
721 | /// let mut extensions = res.extensions_mut().unwrap(); |
722 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
723 | /// extensions.insert(5u32); |
724 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
725 | /// ``` |
726 | pub fn extensions_mut(&mut self) -> Option<&mut Extensions> { |
727 | self.inner.as_mut().ok().map(|h| &mut h.extensions) |
728 | } |
729 | |
730 | /// "Consumes" this builder, using the provided `body` to return a |
731 | /// constructed `Response`. |
732 | /// |
733 | /// # Errors |
734 | /// |
735 | /// This function may return an error if any previously configured argument |
736 | /// failed to parse or get converted to the internal representation. For |
737 | /// example if an invalid `head` was specified via `header("Foo", |
738 | /// "Bar\r\n")` the error will be returned when this function is called |
739 | /// rather than when `header` was called. |
740 | /// |
741 | /// # Examples |
742 | /// |
743 | /// ``` |
744 | /// # use http::*; |
745 | /// |
746 | /// let response = Response::builder() |
747 | /// .body(()) |
748 | /// .unwrap(); |
749 | /// ``` |
750 | pub fn body<T>(self, body: T) -> Result<Response<T>> { |
751 | self.inner.map(move |head| { |
752 | Response { |
753 | head, |
754 | body, |
755 | } |
756 | }) |
757 | } |
758 | |
759 | // private |
760 | |
761 | fn and_then<F>(self, func: F) -> Self |
762 | where |
763 | F: FnOnce(Parts) -> Result<Parts> |
764 | { |
765 | Builder { |
766 | inner: self.inner.and_then(func), |
767 | } |
768 | } |
769 | } |
770 | |
771 | impl Default for Builder { |
772 | #[inline ] |
773 | fn default() -> Builder { |
774 | Builder { |
775 | inner: Ok(Parts::new()), |
776 | } |
777 | } |
778 | } |
779 | |
780 | #[cfg (test)] |
781 | mod tests { |
782 | use super::*; |
783 | |
784 | #[test ] |
785 | fn it_can_map_a_body_from_one_type_to_another() { |
786 | let response = Response::builder().body("some string" ).unwrap(); |
787 | let mapped_response = response.map(|s| { |
788 | assert_eq!(s, "some string" ); |
789 | 123u32 |
790 | }); |
791 | assert_eq!(mapped_response.body(), &123u32); |
792 | } |
793 | } |
794 | |