mirror of https://github.com/rwf2/Rocket.git
Remove with_status and StatusResponder in favor of status module.
This commit is contained in:
parent
0731cd6150
commit
d0136235d7
|
@ -89,6 +89,9 @@ use self::Outcome::*;
|
||||||
|
|
||||||
/// An enum representing success (`Success`), failure (`Failure`), or
|
/// An enum representing success (`Success`), failure (`Failure`), or
|
||||||
/// forwarding (`Forward`).
|
/// forwarding (`Forward`).
|
||||||
|
///
|
||||||
|
/// See the [top level documentation](/rocket/outcome/) for detailed
|
||||||
|
/// information.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
pub enum Outcome<S, E, F> {
|
pub enum Outcome<S, E, F> {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
mod responder;
|
mod responder;
|
||||||
mod redirect;
|
mod redirect;
|
||||||
mod with_status;
|
|
||||||
mod flash;
|
mod flash;
|
||||||
mod named_file;
|
mod named_file;
|
||||||
mod stream;
|
mod stream;
|
||||||
|
@ -23,11 +22,11 @@ mod response;
|
||||||
mod failure;
|
mod failure;
|
||||||
|
|
||||||
pub mod content;
|
pub mod content;
|
||||||
|
pub mod status;
|
||||||
|
|
||||||
pub use self::response::Response;
|
pub use self::response::Response;
|
||||||
pub use self::responder::{Outcome, Responder};
|
pub use self::responder::{Outcome, Responder};
|
||||||
pub use self::redirect::Redirect;
|
pub use self::redirect::Redirect;
|
||||||
pub use self::with_status::StatusResponse;
|
|
||||||
pub use self::flash::Flash;
|
pub use self::flash::Flash;
|
||||||
pub use self::named_file::NamedFile;
|
pub use self::named_file::NamedFile;
|
||||||
pub use self::stream::Stream;
|
pub use self::stream::Stream;
|
||||||
|
|
|
@ -78,6 +78,10 @@ impl<'a, T, E> IntoOutcome<(), (), (StatusCode, FreshHyperResponse<'a>)> for Res
|
||||||
/// Streams the `File` to the client. This is essentially an alias to
|
/// Streams the `File` to the client. This is essentially an alias to
|
||||||
/// Stream<File>.
|
/// Stream<File>.
|
||||||
///
|
///
|
||||||
|
/// * **impl Responder for ()**
|
||||||
|
///
|
||||||
|
/// Responds with an empty body.
|
||||||
|
///
|
||||||
/// * **impl<T: Responder> Responder for Option<T>**
|
/// * **impl<T: Responder> Responder for Option<T>**
|
||||||
///
|
///
|
||||||
/// If the `Option` is `Some`, the wrapped responder is used to respond to
|
/// If the `Option` is `Some`, the wrapped responder is used to respond to
|
||||||
|
@ -158,6 +162,13 @@ impl Responder for File {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Empty response.
|
||||||
|
impl Responder for () {
|
||||||
|
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||||
|
res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Responder> Responder for Option<T> {
|
impl<T: Responder> Responder for Option<T> {
|
||||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||||
if let Some(ref mut val) = *self {
|
if let Some(ref mut val) = *self {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use data::Data;
|
use data::Data;
|
||||||
use outcome::{self, Outcome};
|
use outcome::{self, Outcome};
|
||||||
use http::hyper::StatusCode;
|
use http::hyper::StatusCode;
|
||||||
use response::{Responder, StatusResponse};
|
use response::{Responder, status};
|
||||||
|
|
||||||
/// Type alias for the `Outcome` of a `Handler`.
|
/// Type alias for the `Outcome` of a `Handler`.
|
||||||
pub type Response<'a> = outcome::Outcome<Box<Responder + 'a>, StatusCode, Data>;
|
pub type Response<'a> = outcome::Outcome<Box<Responder + 'a>, StatusCode, Data>;
|
||||||
|
@ -25,7 +25,7 @@ impl<'a> Response<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_raw_status<T: Responder + 'a>(status: u16, body: T) -> Response<'a> {
|
pub fn with_raw_status<T: Responder + 'a>(status: u16, body: T) -> Response<'a> {
|
||||||
let status_code = StatusCode::from_u16(status);
|
let status_code = StatusCode::from_u16(status);
|
||||||
Response::success(StatusResponse::new(status_code, body))
|
Response::success(status::Custom(status_code, body))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
//! Contains types that set the status code and correspoding headers of a
|
||||||
|
//! response.
|
||||||
|
//!
|
||||||
|
//! These types are designed to make it easier to respond with a given status
|
||||||
|
//! code. Each type takes in the minimum number of parameters required to
|
||||||
|
//! construct a proper response with that status code. Some types take in
|
||||||
|
//! responders; when they do, the responder finalizes the response by writing
|
||||||
|
//! out additional headers and, importantly, the body of the response.
|
||||||
|
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
|
||||||
|
use response::{Responder, Outcome};
|
||||||
|
use outcome::IntoOutcome;
|
||||||
|
use http::hyper::{StatusCode, FreshHyperResponse, header};
|
||||||
|
|
||||||
|
/// Sets the status of the response to 201 (Created).
|
||||||
|
///
|
||||||
|
/// The `String` field is set as the value of the `Location` header in the
|
||||||
|
/// response. The optional `Responder` field is used to finalize the response.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
///
|
||||||
|
/// let url = "http://myservice.com/resource.json".to_string();
|
||||||
|
/// let content = "{ 'resource': 'Hello, world!' }";
|
||||||
|
/// let response = status::Created(url, Some(content));
|
||||||
|
/// ```
|
||||||
|
pub struct Created<R: Responder>(pub String, pub Option<R>);
|
||||||
|
|
||||||
|
/// Sets the status code of the response to 201 Created. Sets the `Location`
|
||||||
|
/// header to the `String` parameter in the constructor.
|
||||||
|
///
|
||||||
|
/// The optional responder finalizes the response if it exists. The wrapped
|
||||||
|
/// responder should write the body of the response so that it contains
|
||||||
|
/// information about the created resource. If no responder is provided, the
|
||||||
|
/// response body will be empty.
|
||||||
|
impl<R: Responder> Responder for Created<R> {
|
||||||
|
default fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*res.status_mut() = StatusCode::Created;
|
||||||
|
res.headers_mut().set(header::Location(self.0.clone()));
|
||||||
|
match self.1 {
|
||||||
|
Some(ref mut r) => r.respond(res),
|
||||||
|
None => res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// In addition to setting the status code, `Location` header, and finalizing
|
||||||
|
/// the response with the `Responder`, the `ETag` header is set conditionally if
|
||||||
|
/// a `Responder` is provided that implements `Hash`. The `ETag` header is set
|
||||||
|
/// to a hash value of the responder.
|
||||||
|
impl<R: Responder + Hash> Responder for Created<R> {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*res.status_mut() = StatusCode::Created;
|
||||||
|
res.headers_mut().set(header::Location(self.0.clone()));
|
||||||
|
|
||||||
|
let mut hasher = DefaultHasher::default();
|
||||||
|
match self.1 {
|
||||||
|
Some(ref mut responder) => {
|
||||||
|
responder.hash(&mut hasher);
|
||||||
|
let tag = header::EntityTag::strong(hasher.finish().to_string());
|
||||||
|
res.headers_mut().set(header::ETag(tag));
|
||||||
|
responder.respond(res)
|
||||||
|
}
|
||||||
|
None => res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the status of the response to 202 (Accepted).
|
||||||
|
///
|
||||||
|
/// If a responder is supplied, the remainder of the response is delegated to
|
||||||
|
/// it. If there is no responder, the body of the response will be empty.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// A 202 Accepted response without a body:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
///
|
||||||
|
/// let response = status::Accepted::<()>(None);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// A 202 Accepted response _with_ a body:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
///
|
||||||
|
/// let response = status::Accepted(Some("processing"));
|
||||||
|
/// ```
|
||||||
|
pub struct Accepted<R: Responder>(pub Option<R>);
|
||||||
|
|
||||||
|
/// Sets the status code of the response to 202 Accepted. If the responder is
|
||||||
|
/// `Some`, it is used to finalize the response.
|
||||||
|
impl<R: Responder> Responder for Accepted<R> {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*res.status_mut() = StatusCode::Accepted;
|
||||||
|
match self.0 {
|
||||||
|
Some(ref mut r) => r.respond(res),
|
||||||
|
None => res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the status of the response to 204 (No Content).
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
///
|
||||||
|
/// let response = status::NoContent;
|
||||||
|
/// ```
|
||||||
|
// TODO: This would benefit from Header support.
|
||||||
|
pub struct NoContent;
|
||||||
|
|
||||||
|
/// Sets the status code of the response to 204 No Content. The body of the
|
||||||
|
/// response will be empty.
|
||||||
|
impl Responder for NoContent {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*res.status_mut() = StatusCode::NoContent;
|
||||||
|
res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Sets the status of the response to 205 (Reset Content).
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
///
|
||||||
|
/// let response = status::Reset;
|
||||||
|
/// ```
|
||||||
|
pub struct Reset;
|
||||||
|
|
||||||
|
/// Sets the status code of the response to 205 Reset Content. The body of the
|
||||||
|
/// response will be empty.
|
||||||
|
impl Responder for Reset {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*res.status_mut() = StatusCode::ResetContent;
|
||||||
|
res.send(&[]).into_outcome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a response with the given status code and underyling responder.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::response::status;
|
||||||
|
/// use rocket::http::StatusCode;
|
||||||
|
///
|
||||||
|
/// let response = status::Custom(StatusCode::ImATeapot, "Hi!");
|
||||||
|
/// ```
|
||||||
|
pub struct Custom<R: Responder>(pub StatusCode, pub R);
|
||||||
|
|
||||||
|
/// Sets the status code of the response and then delegates the remainder of the
|
||||||
|
/// response to the wrapped responder.
|
||||||
|
impl<R: Responder> Responder for Custom<R> {
|
||||||
|
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||||
|
*(res.status_mut()) = self.0;
|
||||||
|
self.1.respond(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following are unimplemented.
|
||||||
|
// 206 Partial Content (variant), 203 Non-Authoritative Information (headers).
|
|
@ -1,38 +0,0 @@
|
||||||
use response::{Responder, Outcome};
|
|
||||||
use http::hyper::{StatusCode, FreshHyperResponse};
|
|
||||||
|
|
||||||
/// Responds to the client using a wrapped `Responder` and a given
|
|
||||||
/// `StatusCode`.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct StatusResponse<R: Responder> {
|
|
||||||
status: StatusCode,
|
|
||||||
responder: R,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Responder> StatusResponse<R> {
|
|
||||||
/// Creates a response with the given status code and underyling responder.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use rocket::response::StatusResponse;
|
|
||||||
/// use rocket::http::StatusCode;
|
|
||||||
///
|
|
||||||
/// let response = StatusResponse::new(StatusCode::ImATeapot, "Hi!");
|
|
||||||
/// ```
|
|
||||||
pub fn new(status: StatusCode, responder: R) -> StatusResponse<R> {
|
|
||||||
StatusResponse {
|
|
||||||
status: status,
|
|
||||||
responder: responder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the status code of the response and then delegates the remainder of the
|
|
||||||
/// response to the wrapped responder.
|
|
||||||
impl<R: Responder> Responder for StatusResponse<R> {
|
|
||||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
|
||||||
*(res.status_mut()) = self.status;
|
|
||||||
self.responder.respond(res)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue