From f953cafe27d1c5de0c8b859e485225cfc2c18629 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 13 Jun 2017 09:49:27 -0700 Subject: [PATCH] feat(status): add `StatusCode::try_from(u16)`. This is a temporary function until the `TryFrom` trait stabilizes. BREAKING CHANGE: Removes the undocumented `from_u16` function. Use `StatusCode::try_from` instead. Also makes the `status` module private. All imports of `hyper::status::StatusCode` should be `hyper::StatusCode`. --- src/http/h1/parse.rs | 3 ++- src/http/mod.rs | 2 +- src/lib.rs | 2 +- src/status.rs | 44 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/http/h1/parse.rs b/src/http/h1/parse.rs index c1ead352e3..197f5a1cf0 100644 --- a/src/http/h1/parse.rs +++ b/src/http/h1/parse.rs @@ -160,7 +160,8 @@ impl Http1Transaction for ClientTransaction { httparse::Status::Complete(len) => { trace!("Response.try_parse Complete({})", len); let code = res.code.unwrap(); - let reason = match StatusCode::from_u16(code).canonical_reason() { + let status = try!(StatusCode::try_from(code).map_err(|_| ::Error::Status)); + let reason = match status.canonical_reason() { Some(reason) if reason == res.reason.unwrap() => Cow::Borrowed(reason), _ => Cow::Owned(res.reason.unwrap().to_owned()) }; diff --git a/src/http/mod.rs b/src/http/mod.rs index 7ab0ff7eb2..5e4568d115 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -89,7 +89,7 @@ impl RawStatus { /// Converts this into a StatusCode. #[inline] pub fn status(&self) -> StatusCode { - StatusCode::from_u16(self.0) + StatusCode::try_from(self.0).unwrap() } } diff --git a/src/lib.rs b/src/lib.rs index 3ef683cd8b..ad5ec7cea7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,6 +57,6 @@ mod method; pub mod header; mod http; pub mod server; -pub mod status; +mod status; mod uri; mod version; diff --git a/src/status.rs b/src/status.rs index e12e7216b8..a4f0ea58f9 100644 --- a/src/status.rs +++ b/src/status.rs @@ -213,11 +213,35 @@ pub enum StatusCode { Unregistered(u16), } +#[derive(Debug)] +pub struct InvalidStatusCode { + _inner: (), +} + impl StatusCode { - #[doc(hidden)] - // Not part of public API or API contract. Could disappear. - pub fn from_u16(n: u16) -> StatusCode { + /// Try to convert a `u16` into a `StatusCode`. + /// + /// # Errors + /// + /// This will return an error if the provided argument is not within the + /// range `100...599`. + /// + /// # Note + /// + /// This function is temporary. When the `TryFrom` trait becomes stable, + /// this will be deprecated and replaced by `TryFrom`. + pub fn try_from(n: u16) -> Result { + if n < 100 || n > 599 { + Err(InvalidStatusCode { + _inner: (), + }) + } else { + Ok(StatusCode::from_u16(n)) + } + } + + fn from_u16(n: u16) -> StatusCode { match n { 100 => StatusCode::Continue, 101 => StatusCode::SwitchingProtocols, @@ -490,7 +514,7 @@ impl Copy for StatusCode {} /// Formats the status code, *including* the canonical reason. /// /// ```rust -/// # use hyper::status::StatusCode::{ImATeapot, Unregistered}; +/// # use hyper::StatusCode::{ImATeapot, Unregistered}; /// assert_eq!(format!("{}", ImATeapot), "418 I'm a teapot"); /// assert_eq!(format!("{}", Unregistered(123)), /// "123 "); @@ -750,4 +774,16 @@ mod tests { Some("Network Authentication Required")); } + + #[test] + fn try_from() { + StatusCode::try_from(100).unwrap(); + StatusCode::try_from(599).unwrap(); + StatusCode::try_from(200).unwrap(); + + StatusCode::try_from(99).unwrap_err(); + StatusCode::try_from(600).unwrap_err(); + StatusCode::try_from(0).unwrap_err(); + StatusCode::try_from(1000).unwrap_err(); + } }