From 0d674c57fd0aab04c9cef16077c28531b4c302de Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 14 Apr 2017 01:21:06 -0700 Subject: [PATCH] Return `HeaderMap` from Response::headers(). Remove Response::header_values(). This is a breaking change. A call to `Response::headers()` can be replaced with `Response::headers().iter()`. A call to `Response::header_values()` can be replaced with `Response::headers().get()`. --- examples/cookies/src/tests.rs | 4 +- examples/handlebars_templates/src/tests.rs | 2 +- examples/optional_redirect/src/tests.rs | 2 +- examples/redirect/src/tests.rs | 2 +- lib/src/request/request.rs | 3 +- lib/src/response/responder.rs | 2 +- lib/src/response/response.rs | 91 ++++++++------------ lib/src/rocket.rs | 2 +- lib/tests/head_handling.rs | 4 +- lib/tests/redirect_from_catcher-issue-113.rs | 2 +- 10 files changed, 46 insertions(+), 68 deletions(-) diff --git a/examples/cookies/src/tests.rs b/examples/cookies/src/tests.rs index af9724d3..0528d963 100644 --- a/examples/cookies/src/tests.rs +++ b/examples/cookies/src/tests.rs @@ -12,8 +12,8 @@ fn test_submit() { .header(ContentType::Form) .body("message=Hello from Rocket!"); let response = request.dispatch_with(&rocket); - let cookie_headers: Vec<_> = response.header_values("Set-Cookie").collect(); - let location_headers: Vec<_> = response.header_values("Location").collect(); + let cookie_headers: Vec<_> = response.headers().get("Set-Cookie").collect(); + let location_headers: Vec<_> = response.headers().get("Location").collect(); assert_eq!(response.status(), Status::SeeOther); assert_eq!(cookie_headers, vec!["message=Hello%20from%20Rocket!".to_string()]); diff --git a/examples/handlebars_templates/src/tests.rs b/examples/handlebars_templates/src/tests.rs index 18654b3a..c72a116b 100644 --- a/examples/handlebars_templates/src/tests.rs +++ b/examples/handlebars_templates/src/tests.rs @@ -25,7 +25,7 @@ fn test_root() { assert_eq!(response.status(), Status::SeeOther); assert!(response.body().is_none()); - let location_headers: Vec<_> = response.header_values("Location").collect(); + let location_headers: Vec<_> = response.headers().get("Location").collect(); assert_eq!(location_headers, vec!["/hello/Unknown"]); }); } diff --git a/examples/optional_redirect/src/tests.rs b/examples/optional_redirect/src/tests.rs index d7e50c07..c8680f1d 100644 --- a/examples/optional_redirect/src/tests.rs +++ b/examples/optional_redirect/src/tests.rs @@ -18,7 +18,7 @@ fn test_303(uri: &str, expected_location: &str) { .mount("/", routes![super::root, super::user, super::login]); let mut request = MockRequest::new(Method::Get, uri); let response = request.dispatch_with(&rocket); - let location_headers: Vec<_> = response.header_values("Location").collect(); + let location_headers: Vec<_> = response.headers().get("Location").collect(); assert_eq!(response.status(), Status::SeeOther); assert_eq!(location_headers, vec![expected_location]); diff --git a/examples/redirect/src/tests.rs b/examples/redirect/src/tests.rs index 69848b0d..f14e85eb 100644 --- a/examples/redirect/src/tests.rs +++ b/examples/redirect/src/tests.rs @@ -18,7 +18,7 @@ fn test_root() { run_test!("/", |mut response: Response| { assert!(response.body().is_none()); assert_eq!(response.status(), Status::SeeOther); - for h in response.headers() { + for h in response.headers().iter() { match h.name.as_str() { "Location" => assert_eq!(h.value, "/login"), "Content-Length" => assert_eq!(h.value.parse::().unwrap(), 0), diff --git a/lib/src/request/request.rs b/lib/src/request/request.rs index d5df43ad..323261eb 100644 --- a/lib/src/request/request.rs +++ b/lib/src/request/request.rs @@ -192,7 +192,8 @@ impl<'r> Request<'r> { self.remote = Some(address); } - /// Returns a `HeaderMap` of all of the headers in `self`. + /// Returns a [HeaderMap](/rocket/http/struct.HeaderMap.html) of all of the + /// headers in `self`. /// /// # Example /// diff --git a/lib/src/response/responder.rs b/lib/src/response/responder.rs index 23ad7744..d8b0ebd7 100644 --- a/lib/src/response/responder.rs +++ b/lib/src/response/responder.rs @@ -177,7 +177,7 @@ pub trait Responder<'r> { /// let body_string = response.body().and_then(|b| b.into_string()); /// assert_eq!(body_string, Some("Hello".to_string())); /// -/// let content_type: Vec<_> = response.header_values("Content-Type").collect(); +/// let content_type: Vec<_> = response.headers().get("Content-Type").collect(); /// assert_eq!(content_type.len(), 1); /// assert_eq!(content_type[0], ContentType::Plain.to_string()); /// ``` diff --git a/lib/src/response/response.rs b/lib/src/response/response.rs index 68031529..156b9237 100644 --- a/lib/src/response/response.rs +++ b/lib/src/response/response.rs @@ -243,7 +243,7 @@ impl<'r> ResponseBuilder<'r> { /// .header(ContentType::HTML) /// .finalize(); /// - /// assert_eq!(response.header_values("Content-Type").count(), 1); + /// assert_eq!(response.headers().get("Content-Type").count(), 1); /// ``` #[inline(always)] pub fn header<'h: 'r, H>(&mut self, header: H) -> &mut ResponseBuilder<'r> @@ -274,7 +274,7 @@ impl<'r> ResponseBuilder<'r> { /// .header_adjoin(Accept::text()) /// .finalize(); /// - /// assert_eq!(response.header_values("Accept").count(), 2); + /// assert_eq!(response.headers().get("Accept").count(), 2); /// ``` #[inline(always)] pub fn header_adjoin<'h: 'r, H>(&mut self, header: H) -> &mut ResponseBuilder<'r> @@ -299,7 +299,7 @@ impl<'r> ResponseBuilder<'r> { /// .raw_header("X-Custom", "second") /// .finalize(); /// - /// assert_eq!(response.header_values("X-Custom").count(), 1); + /// assert_eq!(response.headers().get("X-Custom").count(), 1); /// ``` #[inline(always)] pub fn raw_header<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) @@ -326,7 +326,7 @@ impl<'r> ResponseBuilder<'r> { /// .raw_header_adjoin("X-Custom", "second") /// .finalize(); /// - /// assert_eq!(response.header_values("X-Custom").count(), 2); + /// assert_eq!(response.headers().get("X-Custom").count(), 2); /// ``` #[inline(always)] pub fn raw_header_adjoin<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) @@ -444,12 +444,12 @@ impl<'r> ResponseBuilder<'r> { /// assert_eq!(response.status(), Status::NotFound); /// /// # { - /// let ctype: Vec<_> = response.header_values("Content-Type").collect(); + /// let ctype: Vec<_> = response.headers().get("Content-Type").collect(); /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]); /// # } /// /// # { - /// let custom_values: Vec<_> = response.header_values("X-Custom").collect(); + /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect(); /// assert_eq!(custom_values, vec!["value 1"]); /// # } /// ``` @@ -488,12 +488,12 @@ impl<'r> ResponseBuilder<'r> { /// assert_eq!(response.status(), Status::ImATeapot); /// /// # { - /// let ctype: Vec<_> = response.header_values("Content-Type").collect(); + /// let ctype: Vec<_> = response.headers().get("Content-Type").collect(); /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]); /// # } /// /// # { - /// let custom_values: Vec<_> = response.header_values("X-Custom").collect(); + /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect(); /// assert_eq!(custom_values, vec!["value 2", "value 3", "value 1"]); /// # } /// ``` @@ -562,7 +562,7 @@ impl<'r> Response<'r> { /// let mut response = Response::new(); /// /// assert_eq!(response.status(), Status::Ok); - /// assert_eq!(response.headers().count(), 0); + /// assert_eq!(response.headers().len(), 0); /// assert!(response.body().is_none()); /// ``` #[inline(always)] @@ -660,11 +660,8 @@ impl<'r> Response<'r> { self.status = Some(Status::new(code, reason)); } - /// Returns an iterator over all of the headers stored in `self`. Multiple - /// headers with the same name may be returned, but all of the headers with - /// the same name will be appear in a group in the iterator. The values in - /// this group will be emitted in the order they were added to `self`. Aside - /// from this grouping, there are no other ordering guarantees. + /// Returns a [HeaderMap](/rocket/http/struct.HeaderMap.html) of all of the + /// headers in `self`. /// /// # Example /// @@ -676,34 +673,14 @@ impl<'r> Response<'r> { /// response.adjoin_raw_header("X-Custom", "1"); /// response.adjoin_raw_header("X-Custom", "2"); /// - /// let mut headers = response.headers(); - /// assert_eq!(headers.next(), Some(Header::new("X-Custom", "1"))); - /// assert_eq!(headers.next(), Some(Header::new("X-Custom", "2"))); - /// assert_eq!(headers.next(), None); + /// let mut custom_headers = response.headers().iter(); + /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "1"))); + /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "2"))); + /// assert_eq!(custom_headers.next(), None); /// ``` #[inline(always)] - pub fn headers<'a>(&'a self) -> impl Iterator> { - self.headers.iter() - } - - /// Returns an iterator over all of the values stored in `self` for the - /// header with name `name`. The values are returned in FIFO order. - /// - /// # Example - /// - /// ```rust - /// use rocket::Response; - /// - /// let mut response = Response::new(); - /// response.adjoin_raw_header("X-Custom", "1"); - /// response.adjoin_raw_header("X-Custom", "2"); - /// - /// let values: Vec<_> = response.header_values("X-Custom").collect(); - /// assert_eq!(values, vec!["1", "2"]); - /// ``` - #[inline(always)] - pub fn header_values<'h>(&'h self, name: &str) -> impl Iterator { - self.headers.get(name) + pub fn headers(&self) -> &HeaderMap<'r> { + &self.headers } /// Sets the header `header` in `self`. Any existing headers with the name @@ -721,12 +698,12 @@ impl<'r> Response<'r> { /// let mut response = Response::new(); /// /// response.set_header(ContentType::HTML); - /// assert_eq!(response.headers().next(), Some(ContentType::HTML.into())); - /// assert_eq!(response.headers().count(), 1); + /// assert_eq!(response.headers().iter().next(), Some(ContentType::HTML.into())); + /// assert_eq!(response.headers().len(), 1); /// /// response.set_header(ContentType::JSON); - /// assert_eq!(response.headers().next(), Some(ContentType::JSON.into())); - /// assert_eq!(response.headers().count(), 1); + /// assert_eq!(response.headers().iter().next(), Some(ContentType::JSON.into())); + /// assert_eq!(response.headers().len(), 1); /// ``` #[inline(always)] pub fn set_header<'h: 'r, H: Into>>(&mut self, header: H) -> bool { @@ -747,12 +724,12 @@ impl<'r> Response<'r> { /// let mut response = Response::new(); /// /// response.set_raw_header("X-Custom", "1"); - /// assert_eq!(response.headers().next(), Some(Header::new("X-Custom", "1"))); - /// assert_eq!(response.headers().count(), 1); + /// assert_eq!(response.headers().get_one("X-Custom"), Some("1")); + /// assert_eq!(response.headers().len(), 1); /// /// response.set_raw_header("X-Custom", "2"); - /// assert_eq!(response.headers().next(), Some(Header::new("X-Custom", "2"))); - /// assert_eq!(response.headers().count(), 1); + /// assert_eq!(response.headers().get_one("X-Custom"), Some("2")); + /// assert_eq!(response.headers().len(), 1); /// ``` #[inline(always)] pub fn set_raw_header<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) -> bool @@ -778,7 +755,7 @@ impl<'r> Response<'r> { /// response.adjoin_header(Accept::json()); /// response.adjoin_header(Accept::text()); /// - /// let mut accept_headers = response.headers(); + /// let mut accept_headers = response.headers().iter(); /// assert_eq!(accept_headers.next(), Some(Accept::json().into())); /// assert_eq!(accept_headers.next(), Some(Accept::text().into())); /// assert_eq!(accept_headers.next(), None); @@ -805,7 +782,7 @@ impl<'r> Response<'r> { /// response.adjoin_raw_header("X-Custom", "one"); /// response.adjoin_raw_header("X-Custom", "two"); /// - /// let mut custom_headers = response.headers(); + /// let mut custom_headers = response.headers().iter(); /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "one"))); /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "two"))); /// assert_eq!(custom_headers.next(), None); @@ -829,10 +806,10 @@ impl<'r> Response<'r> { /// response.adjoin_raw_header("X-Custom", "one"); /// response.adjoin_raw_header("X-Custom", "two"); /// response.adjoin_raw_header("X-Other", "hi"); - /// assert_eq!(response.headers().count(), 3); + /// assert_eq!(response.headers().len(), 3); /// /// response.remove_header("X-Custom"); - /// assert_eq!(response.headers().count(), 1); + /// assert_eq!(response.headers().len(), 1); /// ``` #[inline(always)] pub fn remove_header(&mut self, name: &str) { @@ -1034,12 +1011,12 @@ impl<'r> Response<'r> { /// assert_eq!(response.status(), Status::NotFound); /// /// # { - /// let ctype: Vec<_> = response.header_values("Content-Type").collect(); + /// let ctype: Vec<_> = response.headers().get("Content-Type").collect(); /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]); /// # } /// /// # { - /// let custom_values: Vec<_> = response.header_values("X-Custom").collect(); + /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect(); /// assert_eq!(custom_values, vec!["value 1"]); /// # } /// ``` @@ -1083,12 +1060,12 @@ impl<'r> Response<'r> { /// assert_eq!(response.status(), Status::ImATeapot); /// /// # { - /// let ctype: Vec<_> = response.header_values("Content-Type").collect(); + /// let ctype: Vec<_> = response.headers().get("Content-Type").collect(); /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]); /// # } /// /// # { - /// let custom_values: Vec<_> = response.header_values("X-Custom").collect(); + /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect(); /// assert_eq!(custom_values, vec!["value 2", "value 3", "value 1"]); /// # } /// ``` @@ -1111,7 +1088,7 @@ impl<'r> fmt::Debug for Response<'r> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "{}", self.status())?; - for header in self.headers() { + for header in self.headers().iter() { writeln!(f, "{}", header)?; } diff --git a/lib/src/rocket.rs b/lib/src/rocket.rs index 262d03a1..9170e9e0 100644 --- a/lib/src/rocket.rs +++ b/lib/src/rocket.rs @@ -121,7 +121,7 @@ impl Rocket { { *hyp_res.status_mut() = hyper::StatusCode::from_u16(response.status().code); - for header in response.headers() { + for header in response.headers().iter() { // FIXME: Using hyper here requires two allocations. let name = header.name.into_string(); let value = Vec::from(header.value.as_bytes()); diff --git a/lib/tests/head_handling.rs b/lib/tests/head_handling.rs index 6b5b2a9a..0c86c067 100644 --- a/lib/tests/head_handling.rs +++ b/lib/tests/head_handling.rs @@ -54,7 +54,7 @@ mod tests { } - let content_type: Vec<_> = response.header_values("Content-Type").collect(); + let content_type: Vec<_> = response.headers().get("Content-Type").collect(); assert_eq!(content_type, vec![ContentType::Plain.to_string()]); let mut req = MockRequest::new(Head, "/empty"); @@ -70,7 +70,7 @@ mod tests { assert_eq!(response.status(), Status::Ok); - let content_type: Vec<_> = response.header_values("Content-Type").collect(); + let content_type: Vec<_> = response.headers().get("Content-Type").collect(); assert_eq!(content_type, vec![ContentType::JSON.to_string()]); } } diff --git a/lib/tests/redirect_from_catcher-issue-113.rs b/lib/tests/redirect_from_catcher-issue-113.rs index 79bae319..c68152a6 100644 --- a/lib/tests/redirect_from_catcher-issue-113.rs +++ b/lib/tests/redirect_from_catcher-issue-113.rs @@ -24,7 +24,7 @@ mod tests { let response = req.dispatch_with(&rocket); println!("Response:\n{:?}", response); - let location: Vec<_> = response.header_values("location").collect(); + let location: Vec<_> = response.headers().get("location").collect(); assert_eq!(response.status(), Status::SeeOther); assert_eq!(location, vec!["/"]); }