| 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::TryInto; |
| 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 | #[derive (Clone)] |
| 180 | pub struct Response<T> { |
| 181 | head: Parts, |
| 182 | body: T, |
| 183 | } |
| 184 | |
| 185 | /// Component parts of an HTTP `Response` |
| 186 | /// |
| 187 | /// The HTTP response head consists of a status, version, and a set of |
| 188 | /// header fields. |
| 189 | #[derive (Clone)] |
| 190 | pub struct Parts { |
| 191 | /// The response's status |
| 192 | pub status: StatusCode, |
| 193 | |
| 194 | /// The response's version |
| 195 | pub version: Version, |
| 196 | |
| 197 | /// The response's headers |
| 198 | pub headers: HeaderMap<HeaderValue>, |
| 199 | |
| 200 | /// The response's extensions |
| 201 | pub extensions: Extensions, |
| 202 | |
| 203 | _priv: (), |
| 204 | } |
| 205 | |
| 206 | /// An HTTP response builder |
| 207 | /// |
| 208 | /// This type can be used to construct an instance of `Response` through a |
| 209 | /// builder-like pattern. |
| 210 | #[derive (Debug)] |
| 211 | pub struct Builder { |
| 212 | inner: Result<Parts>, |
| 213 | } |
| 214 | |
| 215 | impl Response<()> { |
| 216 | /// Creates a new builder-style object to manufacture a `Response` |
| 217 | /// |
| 218 | /// This method returns an instance of `Builder` which can be used to |
| 219 | /// create a `Response`. |
| 220 | /// |
| 221 | /// # Examples |
| 222 | /// |
| 223 | /// ``` |
| 224 | /// # use http::*; |
| 225 | /// let response = Response::builder() |
| 226 | /// .status(200) |
| 227 | /// .header("X-Custom-Foo" , "Bar" ) |
| 228 | /// .body(()) |
| 229 | /// .unwrap(); |
| 230 | /// ``` |
| 231 | #[inline ] |
| 232 | pub fn builder() -> Builder { |
| 233 | Builder::new() |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | impl<T> Response<T> { |
| 238 | /// Creates a new blank `Response` with the body |
| 239 | /// |
| 240 | /// The component parts of this response will be set to their default, e.g. |
| 241 | /// the ok status, no headers, etc. |
| 242 | /// |
| 243 | /// # Examples |
| 244 | /// |
| 245 | /// ``` |
| 246 | /// # use http::*; |
| 247 | /// let response = Response::new("hello world" ); |
| 248 | /// |
| 249 | /// assert_eq!(response.status(), StatusCode::OK); |
| 250 | /// assert_eq!(*response.body(), "hello world" ); |
| 251 | /// ``` |
| 252 | #[inline ] |
| 253 | pub fn new(body: T) -> Response<T> { |
| 254 | Response { |
| 255 | head: Parts::new(), |
| 256 | body, |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | /// Creates a new `Response` with the given head and body |
| 261 | /// |
| 262 | /// # Examples |
| 263 | /// |
| 264 | /// ``` |
| 265 | /// # use http::*; |
| 266 | /// let response = Response::new("hello world" ); |
| 267 | /// let (mut parts, body) = response.into_parts(); |
| 268 | /// |
| 269 | /// parts.status = StatusCode::BAD_REQUEST; |
| 270 | /// let response = Response::from_parts(parts, body); |
| 271 | /// |
| 272 | /// assert_eq!(response.status(), StatusCode::BAD_REQUEST); |
| 273 | /// assert_eq!(*response.body(), "hello world" ); |
| 274 | /// ``` |
| 275 | #[inline ] |
| 276 | pub fn from_parts(parts: Parts, body: T) -> Response<T> { |
| 277 | Response { head: parts, body } |
| 278 | } |
| 279 | |
| 280 | /// Returns the `StatusCode`. |
| 281 | /// |
| 282 | /// # Examples |
| 283 | /// |
| 284 | /// ``` |
| 285 | /// # use http::*; |
| 286 | /// let response: Response<()> = Response::default(); |
| 287 | /// assert_eq!(response.status(), StatusCode::OK); |
| 288 | /// ``` |
| 289 | #[inline ] |
| 290 | pub fn status(&self) -> StatusCode { |
| 291 | self.head.status |
| 292 | } |
| 293 | |
| 294 | /// Returns a mutable reference to the associated `StatusCode`. |
| 295 | /// |
| 296 | /// # Examples |
| 297 | /// |
| 298 | /// ``` |
| 299 | /// # use http::*; |
| 300 | /// let mut response: Response<()> = Response::default(); |
| 301 | /// *response.status_mut() = StatusCode::CREATED; |
| 302 | /// assert_eq!(response.status(), StatusCode::CREATED); |
| 303 | /// ``` |
| 304 | #[inline ] |
| 305 | pub fn status_mut(&mut self) -> &mut StatusCode { |
| 306 | &mut self.head.status |
| 307 | } |
| 308 | |
| 309 | /// Returns a reference to the associated version. |
| 310 | /// |
| 311 | /// # Examples |
| 312 | /// |
| 313 | /// ``` |
| 314 | /// # use http::*; |
| 315 | /// let response: Response<()> = Response::default(); |
| 316 | /// assert_eq!(response.version(), Version::HTTP_11); |
| 317 | /// ``` |
| 318 | #[inline ] |
| 319 | pub fn version(&self) -> Version { |
| 320 | self.head.version |
| 321 | } |
| 322 | |
| 323 | /// Returns a mutable reference to the associated version. |
| 324 | /// |
| 325 | /// # Examples |
| 326 | /// |
| 327 | /// ``` |
| 328 | /// # use http::*; |
| 329 | /// let mut response: Response<()> = Response::default(); |
| 330 | /// *response.version_mut() = Version::HTTP_2; |
| 331 | /// assert_eq!(response.version(), Version::HTTP_2); |
| 332 | /// ``` |
| 333 | #[inline ] |
| 334 | pub fn version_mut(&mut self) -> &mut Version { |
| 335 | &mut self.head.version |
| 336 | } |
| 337 | |
| 338 | /// Returns a reference to the associated header field map. |
| 339 | /// |
| 340 | /// # Examples |
| 341 | /// |
| 342 | /// ``` |
| 343 | /// # use http::*; |
| 344 | /// let response: Response<()> = Response::default(); |
| 345 | /// assert!(response.headers().is_empty()); |
| 346 | /// ``` |
| 347 | #[inline ] |
| 348 | pub fn headers(&self) -> &HeaderMap<HeaderValue> { |
| 349 | &self.head.headers |
| 350 | } |
| 351 | |
| 352 | /// Returns a mutable reference to the associated header field map. |
| 353 | /// |
| 354 | /// # Examples |
| 355 | /// |
| 356 | /// ``` |
| 357 | /// # use http::*; |
| 358 | /// # use http::header::*; |
| 359 | /// let mut response: Response<()> = Response::default(); |
| 360 | /// response.headers_mut().insert(HOST, HeaderValue::from_static("world" )); |
| 361 | /// assert!(!response.headers().is_empty()); |
| 362 | /// ``` |
| 363 | #[inline ] |
| 364 | pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> { |
| 365 | &mut self.head.headers |
| 366 | } |
| 367 | |
| 368 | /// Returns a reference to the associated extensions. |
| 369 | /// |
| 370 | /// # Examples |
| 371 | /// |
| 372 | /// ``` |
| 373 | /// # use http::*; |
| 374 | /// let response: Response<()> = Response::default(); |
| 375 | /// assert!(response.extensions().get::<i32>().is_none()); |
| 376 | /// ``` |
| 377 | #[inline ] |
| 378 | pub fn extensions(&self) -> &Extensions { |
| 379 | &self.head.extensions |
| 380 | } |
| 381 | |
| 382 | /// Returns a mutable reference to the associated extensions. |
| 383 | /// |
| 384 | /// # Examples |
| 385 | /// |
| 386 | /// ``` |
| 387 | /// # use http::*; |
| 388 | /// # use http::header::*; |
| 389 | /// let mut response: Response<()> = Response::default(); |
| 390 | /// response.extensions_mut().insert("hello" ); |
| 391 | /// assert_eq!(response.extensions().get(), Some(&"hello" )); |
| 392 | /// ``` |
| 393 | #[inline ] |
| 394 | pub fn extensions_mut(&mut self) -> &mut Extensions { |
| 395 | &mut self.head.extensions |
| 396 | } |
| 397 | |
| 398 | /// Returns a reference to the associated HTTP body. |
| 399 | /// |
| 400 | /// # Examples |
| 401 | /// |
| 402 | /// ``` |
| 403 | /// # use http::*; |
| 404 | /// let response: Response<String> = Response::default(); |
| 405 | /// assert!(response.body().is_empty()); |
| 406 | /// ``` |
| 407 | #[inline ] |
| 408 | pub fn body(&self) -> &T { |
| 409 | &self.body |
| 410 | } |
| 411 | |
| 412 | /// Returns a mutable reference to the associated HTTP body. |
| 413 | /// |
| 414 | /// # Examples |
| 415 | /// |
| 416 | /// ``` |
| 417 | /// # use http::*; |
| 418 | /// let mut response: Response<String> = Response::default(); |
| 419 | /// response.body_mut().push_str("hello world" ); |
| 420 | /// assert!(!response.body().is_empty()); |
| 421 | /// ``` |
| 422 | #[inline ] |
| 423 | pub fn body_mut(&mut self) -> &mut T { |
| 424 | &mut self.body |
| 425 | } |
| 426 | |
| 427 | /// Consumes the response, returning just the body. |
| 428 | /// |
| 429 | /// # Examples |
| 430 | /// |
| 431 | /// ``` |
| 432 | /// # use http::Response; |
| 433 | /// let response = Response::new(10); |
| 434 | /// let body = response.into_body(); |
| 435 | /// assert_eq!(body, 10); |
| 436 | /// ``` |
| 437 | #[inline ] |
| 438 | pub fn into_body(self) -> T { |
| 439 | self.body |
| 440 | } |
| 441 | |
| 442 | /// Consumes the response returning the head and body parts. |
| 443 | /// |
| 444 | /// # Examples |
| 445 | /// |
| 446 | /// ``` |
| 447 | /// # use http::*; |
| 448 | /// let response: Response<()> = Response::default(); |
| 449 | /// let (parts, body) = response.into_parts(); |
| 450 | /// assert_eq!(parts.status, StatusCode::OK); |
| 451 | /// ``` |
| 452 | #[inline ] |
| 453 | pub fn into_parts(self) -> (Parts, T) { |
| 454 | (self.head, self.body) |
| 455 | } |
| 456 | |
| 457 | /// Consumes the response returning a new response with body mapped to the |
| 458 | /// return type of the passed in function. |
| 459 | /// |
| 460 | /// # Examples |
| 461 | /// |
| 462 | /// ``` |
| 463 | /// # use http::*; |
| 464 | /// let response = Response::builder().body("some string" ).unwrap(); |
| 465 | /// let mapped_response: Response<&[u8]> = response.map(|b| { |
| 466 | /// assert_eq!(b, "some string" ); |
| 467 | /// b.as_bytes() |
| 468 | /// }); |
| 469 | /// assert_eq!(mapped_response.body(), &"some string" .as_bytes()); |
| 470 | /// ``` |
| 471 | #[inline ] |
| 472 | pub fn map<F, U>(self, f: F) -> Response<U> |
| 473 | where |
| 474 | F: FnOnce(T) -> U, |
| 475 | { |
| 476 | Response { |
| 477 | body: f(self.body), |
| 478 | head: self.head, |
| 479 | } |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | impl<T: Default> Default for Response<T> { |
| 484 | #[inline ] |
| 485 | fn default() -> Response<T> { |
| 486 | Response::new(T::default()) |
| 487 | } |
| 488 | } |
| 489 | |
| 490 | impl<T: fmt::Debug> fmt::Debug for Response<T> { |
| 491 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 492 | f&mut DebugStruct<'_, '_>.debug_struct("Response" ) |
| 493 | .field("status" , &self.status()) |
| 494 | .field("version" , &self.version()) |
| 495 | .field("headers" , self.headers()) |
| 496 | // omits Extensions because not useful |
| 497 | .field(name:"body" , self.body()) |
| 498 | .finish() |
| 499 | } |
| 500 | } |
| 501 | |
| 502 | impl Parts { |
| 503 | /// Creates a new default instance of `Parts` |
| 504 | fn new() -> Parts { |
| 505 | Parts { |
| 506 | status: StatusCode::default(), |
| 507 | version: Version::default(), |
| 508 | headers: HeaderMap::default(), |
| 509 | extensions: Extensions::default(), |
| 510 | _priv: (), |
| 511 | } |
| 512 | } |
| 513 | } |
| 514 | |
| 515 | impl fmt::Debug for Parts { |
| 516 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 517 | f&mut DebugStruct<'_, '_>.debug_struct("Parts" ) |
| 518 | .field("status" , &self.status) |
| 519 | .field("version" , &self.version) |
| 520 | .field(name:"headers" , &self.headers) |
| 521 | // omits Extensions because not useful |
| 522 | // omits _priv because not useful |
| 523 | .finish() |
| 524 | } |
| 525 | } |
| 526 | |
| 527 | impl Builder { |
| 528 | /// Creates a new default instance of `Builder` to construct either a |
| 529 | /// `Head` or a `Response`. |
| 530 | /// |
| 531 | /// # Examples |
| 532 | /// |
| 533 | /// ``` |
| 534 | /// # use http::*; |
| 535 | /// |
| 536 | /// let response = response::Builder::new() |
| 537 | /// .status(200) |
| 538 | /// .body(()) |
| 539 | /// .unwrap(); |
| 540 | /// ``` |
| 541 | #[inline ] |
| 542 | pub fn new() -> Builder { |
| 543 | Builder::default() |
| 544 | } |
| 545 | |
| 546 | /// Set the HTTP status for this response. |
| 547 | /// |
| 548 | /// By default this is `200`. |
| 549 | /// |
| 550 | /// # Examples |
| 551 | /// |
| 552 | /// ``` |
| 553 | /// # use http::*; |
| 554 | /// |
| 555 | /// let response = Response::builder() |
| 556 | /// .status(200) |
| 557 | /// .body(()) |
| 558 | /// .unwrap(); |
| 559 | /// ``` |
| 560 | pub fn status<T>(self, status: T) -> Builder |
| 561 | where |
| 562 | T: TryInto<StatusCode>, |
| 563 | <T as TryInto<StatusCode>>::Error: Into<crate::Error>, |
| 564 | { |
| 565 | self.and_then(move |mut head| { |
| 566 | head.status = status.try_into().map_err(Into::into)?; |
| 567 | Ok(head) |
| 568 | }) |
| 569 | } |
| 570 | |
| 571 | /// Set the HTTP version for this response. |
| 572 | /// |
| 573 | /// By default this is HTTP/1.1 |
| 574 | /// |
| 575 | /// # Examples |
| 576 | /// |
| 577 | /// ``` |
| 578 | /// # use http::*; |
| 579 | /// |
| 580 | /// let response = Response::builder() |
| 581 | /// .version(Version::HTTP_2) |
| 582 | /// .body(()) |
| 583 | /// .unwrap(); |
| 584 | /// ``` |
| 585 | pub fn version(self, version: Version) -> Builder { |
| 586 | self.and_then(move |mut head| { |
| 587 | head.version = version; |
| 588 | Ok(head) |
| 589 | }) |
| 590 | } |
| 591 | |
| 592 | /// Appends a header to this response builder. |
| 593 | /// |
| 594 | /// This function will append the provided key/value as a header to the |
| 595 | /// internal `HeaderMap` being constructed. Essentially this is equivalent |
| 596 | /// to calling `HeaderMap::append`. |
| 597 | /// |
| 598 | /// # Examples |
| 599 | /// |
| 600 | /// ``` |
| 601 | /// # use http::*; |
| 602 | /// # use http::header::HeaderValue; |
| 603 | /// |
| 604 | /// let response = Response::builder() |
| 605 | /// .header("Content-Type" , "text/html" ) |
| 606 | /// .header("X-Custom-Foo" , "bar" ) |
| 607 | /// .header("content-length" , 0) |
| 608 | /// .body(()) |
| 609 | /// .unwrap(); |
| 610 | /// ``` |
| 611 | pub fn header<K, V>(self, key: K, value: V) -> Builder |
| 612 | where |
| 613 | K: TryInto<HeaderName>, |
| 614 | <K as TryInto<HeaderName>>::Error: Into<crate::Error>, |
| 615 | V: TryInto<HeaderValue>, |
| 616 | <V as TryInto<HeaderValue>>::Error: Into<crate::Error>, |
| 617 | { |
| 618 | self.and_then(move |mut head| { |
| 619 | let name = key.try_into().map_err(Into::into)?; |
| 620 | let value = value.try_into().map_err(Into::into)?; |
| 621 | head.headers.try_append(name, value)?; |
| 622 | Ok(head) |
| 623 | }) |
| 624 | } |
| 625 | |
| 626 | /// Get header on this response builder. |
| 627 | /// |
| 628 | /// When builder has error returns None. |
| 629 | /// |
| 630 | /// # Example |
| 631 | /// |
| 632 | /// ``` |
| 633 | /// # use http::Response; |
| 634 | /// # use http::header::HeaderValue; |
| 635 | /// let res = Response::builder() |
| 636 | /// .header("Accept" , "text/html" ) |
| 637 | /// .header("X-Custom-Foo" , "bar" ); |
| 638 | /// let headers = res.headers_ref().unwrap(); |
| 639 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 640 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 641 | /// ``` |
| 642 | pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> { |
| 643 | self.inner.as_ref().ok().map(|h| &h.headers) |
| 644 | } |
| 645 | |
| 646 | /// Get header on this response builder. |
| 647 | /// when builder has error returns None |
| 648 | /// |
| 649 | /// # Example |
| 650 | /// |
| 651 | /// ``` |
| 652 | /// # use http::*; |
| 653 | /// # use http::header::HeaderValue; |
| 654 | /// # use http::response::Builder; |
| 655 | /// let mut res = Response::builder(); |
| 656 | /// { |
| 657 | /// let headers = res.headers_mut().unwrap(); |
| 658 | /// headers.insert("Accept" , HeaderValue::from_static("text/html" )); |
| 659 | /// headers.insert("X-Custom-Foo" , HeaderValue::from_static("bar" )); |
| 660 | /// } |
| 661 | /// let headers = res.headers_ref().unwrap(); |
| 662 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 663 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 664 | /// ``` |
| 665 | pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> { |
| 666 | self.inner.as_mut().ok().map(|h| &mut h.headers) |
| 667 | } |
| 668 | |
| 669 | /// Adds an extension to this builder |
| 670 | /// |
| 671 | /// # Examples |
| 672 | /// |
| 673 | /// ``` |
| 674 | /// # use http::*; |
| 675 | /// |
| 676 | /// let response = Response::builder() |
| 677 | /// .extension("My Extension" ) |
| 678 | /// .body(()) |
| 679 | /// .unwrap(); |
| 680 | /// |
| 681 | /// assert_eq!(response.extensions().get::<&'static str>(), |
| 682 | /// Some(&"My Extension" )); |
| 683 | /// ``` |
| 684 | pub fn extension<T>(self, extension: T) -> Builder |
| 685 | where |
| 686 | T: Clone + Any + Send + Sync + 'static, |
| 687 | { |
| 688 | self.and_then(move |mut head| { |
| 689 | head.extensions.insert(extension); |
| 690 | Ok(head) |
| 691 | }) |
| 692 | } |
| 693 | |
| 694 | /// Get a reference to the extensions for this response builder. |
| 695 | /// |
| 696 | /// If the builder has an error, this returns `None`. |
| 697 | /// |
| 698 | /// # Example |
| 699 | /// |
| 700 | /// ``` |
| 701 | /// # use http::Response; |
| 702 | /// let res = Response::builder().extension("My Extension" ).extension(5u32); |
| 703 | /// let extensions = res.extensions_ref().unwrap(); |
| 704 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 705 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 706 | /// ``` |
| 707 | pub fn extensions_ref(&self) -> Option<&Extensions> { |
| 708 | self.inner.as_ref().ok().map(|h| &h.extensions) |
| 709 | } |
| 710 | |
| 711 | /// Get a mutable reference to the extensions for this response builder. |
| 712 | /// |
| 713 | /// If the builder has an error, this returns `None`. |
| 714 | /// |
| 715 | /// # Example |
| 716 | /// |
| 717 | /// ``` |
| 718 | /// # use http::Response; |
| 719 | /// let mut res = Response::builder().extension("My Extension" ); |
| 720 | /// let mut extensions = res.extensions_mut().unwrap(); |
| 721 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 722 | /// extensions.insert(5u32); |
| 723 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 724 | /// ``` |
| 725 | pub fn extensions_mut(&mut self) -> Option<&mut Extensions> { |
| 726 | self.inner.as_mut().ok().map(|h| &mut h.extensions) |
| 727 | } |
| 728 | |
| 729 | /// "Consumes" this builder, using the provided `body` to return a |
| 730 | /// constructed `Response`. |
| 731 | /// |
| 732 | /// # Errors |
| 733 | /// |
| 734 | /// This function may return an error if any previously configured argument |
| 735 | /// failed to parse or get converted to the internal representation. For |
| 736 | /// example if an invalid `head` was specified via `header("Foo", |
| 737 | /// "Bar\r\n")` the error will be returned when this function is called |
| 738 | /// rather than when `header` was called. |
| 739 | /// |
| 740 | /// # Examples |
| 741 | /// |
| 742 | /// ``` |
| 743 | /// # use http::*; |
| 744 | /// |
| 745 | /// let response = Response::builder() |
| 746 | /// .body(()) |
| 747 | /// .unwrap(); |
| 748 | /// ``` |
| 749 | pub fn body<T>(self, body: T) -> Result<Response<T>> { |
| 750 | self.inner.map(move |head| Response { head, body }) |
| 751 | } |
| 752 | |
| 753 | // private |
| 754 | |
| 755 | fn and_then<F>(self, func: F) -> Self |
| 756 | where |
| 757 | F: FnOnce(Parts) -> Result<Parts>, |
| 758 | { |
| 759 | Builder { |
| 760 | inner: self.inner.and_then(func), |
| 761 | } |
| 762 | } |
| 763 | } |
| 764 | |
| 765 | impl Default for Builder { |
| 766 | #[inline ] |
| 767 | fn default() -> Builder { |
| 768 | Builder { |
| 769 | inner: Ok(Parts::new()), |
| 770 | } |
| 771 | } |
| 772 | } |
| 773 | |
| 774 | #[cfg (test)] |
| 775 | mod tests { |
| 776 | use super::*; |
| 777 | |
| 778 | #[test ] |
| 779 | fn it_can_map_a_body_from_one_type_to_another() { |
| 780 | let response = Response::builder().body("some string" ).unwrap(); |
| 781 | let mapped_response = response.map(|s| { |
| 782 | assert_eq!(s, "some string" ); |
| 783 | 123u32 |
| 784 | }); |
| 785 | assert_eq!(mapped_response.body(), &123u32); |
| 786 | } |
| 787 | } |
| 788 | |