Implement 'Responder' for 'Status'.

This commit obviates the following removed types:

  * response::Failure
  * response::status::NoContent
  * response::status::Reset

Closes #489.
This commit is contained in:
Sergio Benitez 2018-10-31 03:51:45 -07:00
parent 16a65a9a45
commit 41de1e62fb
6 changed files with 57 additions and 76 deletions

View File

@ -1,20 +0,0 @@
use request::Request;
use response::{Response, Responder};
use http::Status;
/// A failing response; simply forwards to the catcher for the given
/// `Status`.
#[derive(Debug)]
pub struct Failure(pub Status);
impl Responder<'static> for Failure {
fn respond_to(self, _: &Request) -> Result<Response<'static>, Status> {
Err(self.0)
}
}
impl From<Status> for Failure {
fn from(status: Status) -> Self {
Failure(status)
}
}

View File

@ -25,7 +25,6 @@ mod redirect;
mod named_file;
mod stream;
mod response;
mod failure;
crate mod flash;
@ -38,7 +37,6 @@ pub use self::redirect::Redirect;
pub use self::flash::Flash;
pub use self::named_file::NamedFile;
pub use self::stream::Stream;
pub use self::failure::Failure;
#[doc(inline)] pub use self::content::Content;
/// Type alias for the `Result` of a `Responder::respond` call.

View File

@ -2,7 +2,7 @@ use std::fs::File;
use std::io::{Cursor, BufReader};
use std::fmt;
use http::{Status, ContentType};
use http::{Status, ContentType, StatusClass};
use response::{self, Response, Body};
use request::Request;
@ -290,3 +290,36 @@ impl<'r, R: Responder<'r>, E: Responder<'r> + fmt::Debug> Responder<'r> for Resu
}
}
}
/// The response generated by `Status` depends on the status code itself. The
/// table below summarizes the functionality:
///
/// | Status Code Range | Response |
/// |-------------------|---------------------------------------|
/// | [400, 599] | Forwards to catcher for given status. |
/// | 100, [200, 205] | Empty with status of `self`. |
/// | All others. | Invalid. Errors to `500` catcher. |
///
/// In short, a client or server error status codes will forward to the
/// corresponding error catcher, a successful status code less than `206` or
/// `100` responds with any empty body and the given status code, and all other
/// status code emit an error message and forward to the `500` (internal server
/// error) catcher.
impl<'r> Responder<'r> for Status {
fn respond_to(self, _: &Request) -> response::Result<'r> {
match self.class() {
StatusClass::ClientError | StatusClass::ServerError => Err(self),
StatusClass::Success if self.code < 206 => {
Response::build().status(self).ok()
}
StatusClass::Informational if self.code == 100 => {
Response::build().status(self).ok()
}
_ => {
error_!("Invalid status used as responder: {}.", self);
warn_!("Fowarding to 500 (Internal Server Error) catcher.");
Err(Status::InternalServerError)
}
}
}
}

View File

@ -111,50 +111,6 @@ impl<'r, R: Responder<'r>> Responder<'r> for Accepted<R> {
}
}
/// Sets the status of the response to 204 (No Content).
///
/// # Example
///
/// ```rust
/// use rocket::response::status;
///
/// # #[allow(unused_variables)]
/// let response = status::NoContent;
/// ```
// TODO: This would benefit from Header support.
#[derive(Debug, Clone, PartialEq)]
pub struct NoContent;
/// Sets the status code of the response to 204 No Content. The body of the
/// response will be empty.
impl<'r> Responder<'r> for NoContent {
fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> {
Response::build().status(Status::NoContent).ok()
}
}
/// Sets the status of the response to 205 (Reset Content).
///
/// # Example
///
/// ```rust
/// use rocket::response::status;
///
/// # #[allow(unused_variables)]
/// let response = status::Reset;
/// ```
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Reset;
/// Sets the status code of the response to 205 Reset Content. The body of the
/// response will be empty.
impl Responder<'static> for Reset {
fn respond_to(self, _: &Request) -> Result<Response<'static>, Status> {
Response::build().status(Status::ResetContent).ok()
}
}
/// Sets the status of the response to 400 (Bad Request).
///
/// If a responder is supplied, the remainder of the response is delegated to

View File

@ -2,11 +2,11 @@
#[macro_use] extern crate rocket;
use rocket::response::{status, content};
use rocket::{http::Status, response::content};
#[get("/empty")]
fn empty() -> status::NoContent {
status::NoContent
fn empty() -> Status {
Status::NoContent
}
#[get("/")]

View File

@ -78,20 +78,34 @@ return an HTML page with the status code and description. If there is no catcher
for a custom status code, Rocket uses the **500** error catcher to return a
response.
### Status
While not encouraged, you can also forward a request to a catcher manually by
using the [`Failure`](@api/rocket/response/struct.Failure.html)
type. For instance, to forward to the catcher for **406 - Not Acceptable**, you
would write:
returning a [`Status`] directly. For instance, to forward to the catcher for
**406: Not Acceptable**, you would write:
```rust
use rocket::response::Failure;
use rocket::http::Status;
#[get("/")]
fn just_fail() -> Failure {
Failure(Status::NotAcceptable)
fn just_fail() -> Status {
Status::NotAcceptable
}
```
The response generated by `Status` depends on the status code itself. As
indicated above, for error status codes (in range [400, 599]), `Status` forwards
to the corresponding error catcher. The table below summarizes responses
generated by `Status` for these and other codes:
| Status Code Range | Response |
|-------------------|---------------------------------------|
| [400, 599] | Forwards to catcher for given status. |
| 100, [200, 205] | Empty with given status. |
| All others. | Invalid. Errors to `500` catcher. |
[`Status`]: https://api.rocket.rs/v0.4/rocket/http/struct.Status.html
## Custom Responders
The [`Responder`] trait documentation details how to implement your own custom