Skip to content

Commit

Permalink
Merge pull request #118 from tirr-c/response-status
Browse files Browse the repository at this point in the history
Add status code modifier for IntoResponse
  • Loading branch information
aturon authored Jan 15, 2019
2 parents 14a13e5 + 8be6d4c commit 5be7493
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
10 changes: 2 additions & 8 deletions examples/default_handler.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
#![feature(async_await)]

use http::status::StatusCode;
use tide::body;
use tide::IntoResponse;

fn main() {
let mut app = tide::App::new(());
app.at("/").get(async || "Hello, world!");

app.default_handler(async || {
http::Response::builder()
.status(StatusCode::NOT_FOUND)
.header("Content-Type", "text/plain")
.body(body::Body::from(\\_(ツ)_/¯".to_string().into_bytes()))
.unwrap()
});
app.default_handler(async || \\_(ツ)_/¯".with_status(StatusCode::NOT_FOUND));

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
Expand Down
42 changes: 42 additions & 0 deletions src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,22 @@ pub type Response = http::Response<Body>;

/// A value that is synchronously convertable into a `Response`.
pub trait IntoResponse: Send + 'static + Sized {
/// Convert the value into a `Response`.
fn into_response(self) -> Response;

/// Create a new `IntoResponse` value that will respond with the given status code.
///
/// ```
/// # use tide::IntoResponse;
/// let resp = "Hello, 404!".with_status(http::status::StatusCode::NOT_FOUND).into_response();
/// assert_eq!(resp.status(), http::status::StatusCode::NOT_FOUND);
/// ```
fn with_status(self, status: http::status::StatusCode) -> WithStatus<Self> {
WithStatus {
inner: self,
status,
}
}
}

impl IntoResponse for () {
Expand Down Expand Up @@ -80,3 +95,30 @@ impl<T: Send + 'static + Into<Body>> IntoResponse for http::Response<T> {
self.map(Into::into)
}
}

/// A response type that modifies the status code.
pub struct WithStatus<R> {
inner: R,
status: http::status::StatusCode,
}

impl<R: IntoResponse> IntoResponse for WithStatus<R> {
fn into_response(self) -> Response {
let mut resp = self.inner.into_response();
*resp.status_mut() = self.status;
resp
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_status() {
let resp = "foo"
.with_status(http::status::StatusCode::NOT_FOUND)
.into_response();
assert_eq!(resp.status(), http::status::StatusCode::NOT_FOUND);
}
}

0 comments on commit 5be7493

Please sign in to comment.