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`.
This commit is contained in:
Sean McArthur
2017-06-13 09:49:27 -07:00
parent c166268c07
commit f953cafe27
4 changed files with 44 additions and 7 deletions

View File

@@ -160,7 +160,8 @@ impl Http1Transaction for ClientTransaction {
httparse::Status::Complete(len) => { httparse::Status::Complete(len) => {
trace!("Response.try_parse Complete({})", len); trace!("Response.try_parse Complete({})", len);
let code = res.code.unwrap(); 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), Some(reason) if reason == res.reason.unwrap() => Cow::Borrowed(reason),
_ => Cow::Owned(res.reason.unwrap().to_owned()) _ => Cow::Owned(res.reason.unwrap().to_owned())
}; };

View File

@@ -89,7 +89,7 @@ impl RawStatus {
/// Converts this into a StatusCode. /// Converts this into a StatusCode.
#[inline] #[inline]
pub fn status(&self) -> StatusCode { pub fn status(&self) -> StatusCode {
StatusCode::from_u16(self.0) StatusCode::try_from(self.0).unwrap()
} }
} }

View File

@@ -57,6 +57,6 @@ mod method;
pub mod header; pub mod header;
mod http; mod http;
pub mod server; pub mod server;
pub mod status; mod status;
mod uri; mod uri;
mod version; mod version;

View File

@@ -213,11 +213,35 @@ pub enum StatusCode {
Unregistered(u16), Unregistered(u16),
} }
#[derive(Debug)]
pub struct InvalidStatusCode {
_inner: (),
}
impl StatusCode { impl StatusCode {
#[doc(hidden)] /// Try to convert a `u16` into a `StatusCode`.
// Not part of public API or API contract. Could disappear. ///
pub fn from_u16(n: u16) -> 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<u16>`.
pub fn try_from(n: u16) -> Result<StatusCode, InvalidStatusCode> {
if n < 100 || n > 599 {
Err(InvalidStatusCode {
_inner: (),
})
} else {
Ok(StatusCode::from_u16(n))
}
}
fn from_u16(n: u16) -> StatusCode {
match n { match n {
100 => StatusCode::Continue, 100 => StatusCode::Continue,
101 => StatusCode::SwitchingProtocols, 101 => StatusCode::SwitchingProtocols,
@@ -490,7 +514,7 @@ impl Copy for StatusCode {}
/// Formats the status code, *including* the canonical reason. /// Formats the status code, *including* the canonical reason.
/// ///
/// ```rust /// ```rust
/// # use hyper::status::StatusCode::{ImATeapot, Unregistered}; /// # use hyper::StatusCode::{ImATeapot, Unregistered};
/// assert_eq!(format!("{}", ImATeapot), "418 I'm a teapot"); /// assert_eq!(format!("{}", ImATeapot), "418 I'm a teapot");
/// assert_eq!(format!("{}", Unregistered(123)), /// assert_eq!(format!("{}", Unregistered(123)),
/// "123 <unknown status code>"); /// "123 <unknown status code>");
@@ -750,4 +774,16 @@ mod tests {
Some("Network Authentication Required")); 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();
}
} }