mirror of https://github.com/rwf2/Rocket.git
Remove RequestOutcome, ResponseOutcome in favor of Outcome. Remove Failure response type.
This commit is contained in:
parent
6a6efaf56b
commit
5447f81f77
|
@ -4,8 +4,9 @@ extern crate serde_json;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::io::Read;
|
||||
|
||||
use rocket::outcome::Outcome::*;
|
||||
use rocket::request::{Request, Data, FromData, DataOutcome};
|
||||
use rocket::response::{Responder, ResponseOutcome, data};
|
||||
use rocket::response::{self, Responder, data};
|
||||
use rocket::http::StatusCode;
|
||||
use rocket::http::hyper::FreshHyperResponse;
|
||||
|
||||
|
@ -82,12 +83,12 @@ impl<T: Deserialize> FromData for JSON<T> {
|
|||
}
|
||||
|
||||
impl<T: Serialize> Responder for JSON<T> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> response::Outcome<'a> {
|
||||
match serde_json::to_string(&self.0) {
|
||||
Ok(json_string) => data::JSON(json_string).respond(res),
|
||||
Err(e) => {
|
||||
error_!("JSON failed to serialize: {:?}", e);
|
||||
ResponseOutcome::forward(StatusCode::BadRequest, res)
|
||||
Forward((StatusCode::BadRequest, res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@ use std::path::{Path, PathBuf};
|
|||
use std::collections::HashMap;
|
||||
|
||||
use rocket::config;
|
||||
use rocket::response::{Content, ResponseOutcome, Responder};
|
||||
use rocket::response::{Content, Outcome, Responder};
|
||||
use rocket::http::hyper::FreshHyperResponse;
|
||||
use rocket::http::{ContentType, StatusCode};
|
||||
use rocket::Outcome::*;
|
||||
|
||||
/// The Template type implements generic support for template rendering in
|
||||
/// Rocket.
|
||||
|
@ -159,7 +160,7 @@ impl Template {
|
|||
}
|
||||
|
||||
impl Responder for Template {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
let content_type = match self.1 {
|
||||
Some(ref ext) => ContentType::from_extension(ext),
|
||||
None => ContentType::html()
|
||||
|
@ -167,7 +168,7 @@ impl Responder for Template {
|
|||
|
||||
match self.0 {
|
||||
Some(ref render) => Content(content_type, render.as_str()).respond(res),
|
||||
None => ResponseOutcome::forward(StatusCode::InternalServerError, res),
|
||||
None => Forward((StatusCode::InternalServerError, res)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
extern crate rocket;
|
||||
|
||||
use std::fmt;
|
||||
use rocket::request::{Request, FromRequest, RequestOutcome};
|
||||
use rocket::request::{self, Request, FromRequest};
|
||||
use rocket::outcome::Outcome::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct HeaderCount(usize);
|
||||
|
@ -17,8 +18,8 @@ impl fmt::Display for HeaderCount {
|
|||
|
||||
impl<'r> FromRequest<'r> for HeaderCount {
|
||||
type Error = ();
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
RequestOutcome::success(HeaderCount(request.headers().len()))
|
||||
fn from_request(request: &'r Request) -> request::Outcome<Self, ()> {
|
||||
Success(HeaderCount(request.headers().len()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ pub use request::{Request, Data};
|
|||
pub use error::Error;
|
||||
pub use catcher::Catcher;
|
||||
pub use rocket::Rocket;
|
||||
pub use outcome::{Outcome, IntoOutcome};
|
||||
|
||||
/// Alias to Rocket::ignite().
|
||||
pub fn ignite() -> Rocket {
|
||||
|
|
|
@ -85,6 +85,9 @@ use term_painter::Color::*;
|
|||
use term_painter::Color;
|
||||
use term_painter::ToStyle;
|
||||
|
||||
use self::Outcome::*;
|
||||
use http::hyper::{FreshHyperResponse, StatusCode};
|
||||
|
||||
/// An enum representing success (`Success`), failure (`Failure`), or
|
||||
/// forwarding (`Forward`).
|
||||
#[must_use]
|
||||
|
@ -98,6 +101,28 @@ pub enum Outcome<S, E, F> {
|
|||
Forward(F),
|
||||
}
|
||||
|
||||
pub trait IntoOutcome<S, E, F> {
|
||||
fn into_outcome(self) -> Outcome<S, E, F>;
|
||||
}
|
||||
|
||||
impl<T, E> IntoOutcome<T, (StatusCode, E), ()> for Result<T, E> {
|
||||
fn into_outcome(self) -> Outcome<T, (StatusCode, E), ()> {
|
||||
match self {
|
||||
Ok(val) => Success(val),
|
||||
Err(val) => Failure((StatusCode::BadRequest, val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, E> IntoOutcome<(), (), (StatusCode, FreshHyperResponse<'a>)> for Result<T, E> {
|
||||
fn into_outcome(self) -> Outcome<(), (), (StatusCode, FreshHyperResponse<'a>)> {
|
||||
match self {
|
||||
Ok(_) => Success(()),
|
||||
Err(_) => Failure(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, E, F> Outcome<S, E, F> {
|
||||
/// Unwraps the Outcome, yielding the contents of a Success.
|
||||
///
|
||||
|
@ -117,7 +142,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn unwrap(self) -> S {
|
||||
match self {
|
||||
Outcome::Success(val) => val,
|
||||
Success(val) => val,
|
||||
_ => panic!("Expected a successful outcome!")
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +167,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn is_success(&self) -> bool {
|
||||
match *self {
|
||||
Outcome::Success(_) => true,
|
||||
Success(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +192,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn is_failure(&self) -> bool {
|
||||
match *self {
|
||||
Outcome::Failure(_) => true,
|
||||
Failure(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +217,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn is_forward(&self) -> bool {
|
||||
match *self {
|
||||
Outcome::Forward(_) => true,
|
||||
Forward(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +243,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn succeeded(self) -> Option<S> {
|
||||
match self {
|
||||
Outcome::Success(val) => Some(val),
|
||||
Success(val) => Some(val),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +269,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn failed(self) -> Option<E> {
|
||||
match self {
|
||||
Outcome::Failure(val) => Some(val),
|
||||
Failure(val) => Some(val),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +295,7 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn forwarded(self) -> Option<F> {
|
||||
match self {
|
||||
Outcome::Forward(val) => Some(val),
|
||||
Forward(val) => Some(val),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -290,9 +315,9 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn as_ref(&self) -> Outcome<&S, &E, &F> {
|
||||
match *self {
|
||||
Outcome::Success(ref val) => Outcome::Success(val),
|
||||
Outcome::Failure(ref val) => Outcome::Failure(val),
|
||||
Outcome::Forward(ref val) => Outcome::Forward(val),
|
||||
Success(ref val) => Success(val),
|
||||
Failure(ref val) => Failure(val),
|
||||
Forward(ref val) => Forward(val),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,18 +337,18 @@ impl<S, E, F> Outcome<S, E, F> {
|
|||
#[inline(always)]
|
||||
pub fn as_mut(&mut self) -> Outcome<&mut S, &mut E, &mut F> {
|
||||
match *self {
|
||||
Outcome::Success(ref mut val) => Outcome::Success(val),
|
||||
Outcome::Failure(ref mut val) => Outcome::Failure(val),
|
||||
Outcome::Forward(ref mut val) => Outcome::Forward(val),
|
||||
Success(ref mut val) => Success(val),
|
||||
Failure(ref mut val) => Failure(val),
|
||||
Forward(ref mut val) => Forward(val),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn formatting(&self) -> (Color, &'static str) {
|
||||
match *self {
|
||||
Outcome::Success(..) => (Green, "Succcess"),
|
||||
Outcome::Failure(..) => (Red, "Failure"),
|
||||
Outcome::Forward(..) => (Yellow, "Forward"),
|
||||
Success(..) => (Green, "Succcess"),
|
||||
Failure(..) => (Red, "Failure"),
|
||||
Forward(..) => (Yellow, "Forward"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,83 +1,59 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use outcome;
|
||||
use request::Request;
|
||||
use outcome::Outcome;
|
||||
use outcome::Outcome::*;
|
||||
use http::{StatusCode, ContentType, Method, Cookies};
|
||||
|
||||
/// Type alias for the `Outcome` of a `FromRequest` conversion.
|
||||
pub type RequestOutcome<T, E> = Outcome<T, (StatusCode, E), ()>;
|
||||
|
||||
impl<T, E> RequestOutcome<T, E> {
|
||||
#[inline(always)]
|
||||
pub fn of(result: Result<T, E>) -> Self {
|
||||
match result {
|
||||
Ok(val) => Outcome::Success(val),
|
||||
Err(_) => Outcome::Forward(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn success(t: T) -> Self {
|
||||
Outcome::Success(t)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn failure(code: StatusCode, error: E) -> Self {
|
||||
Outcome::Failure((code, error))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn forward() -> Self {
|
||||
Outcome::Forward(())
|
||||
}
|
||||
}
|
||||
pub type Outcome<T, E> = outcome::Outcome<T, (StatusCode, E), ()>;
|
||||
|
||||
pub trait FromRequest<'r>: Sized {
|
||||
type Error: Debug;
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error>;
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error>;
|
||||
}
|
||||
|
||||
impl<'r> FromRequest<'r> for &'r Request {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
RequestOutcome::success(request)
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
Success(request)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> FromRequest<'r> for Method {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
RequestOutcome::success(request.method)
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
Success(request.method)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> FromRequest<'r> for &'r Cookies {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
RequestOutcome::success(request.cookies())
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
Success(request.cookies())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> FromRequest<'r> for ContentType {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
RequestOutcome::success(request.content_type())
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
Success(request.content_type())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Result<T, T::Error> {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
match T::from_request(request) {
|
||||
Outcome::Success(val) => RequestOutcome::success(Ok(val)),
|
||||
Outcome::Failure((_, e)) => RequestOutcome::success(Err(e)),
|
||||
Outcome::Forward(_) => RequestOutcome::forward(),
|
||||
Success(val) => Success(Ok(val)),
|
||||
Failure((_, e)) => Success(Err(e)),
|
||||
Forward(_) => Forward(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,11 +61,11 @@ impl<'r, T: FromRequest<'r>> FromRequest<'r> for Result<T, T::Error> {
|
|||
impl<'r, T: FromRequest<'r>> FromRequest<'r> for Option<T> {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
fn from_request(request: &'r Request) -> Outcome<Self, Self::Error> {
|
||||
match T::from_request(request) {
|
||||
Outcome::Success(val) => RequestOutcome::success(Some(val)),
|
||||
Outcome::Failure(_) => RequestOutcome::success(None),
|
||||
Outcome::Forward(_) => RequestOutcome::success(None),
|
||||
Success(val) => Success(Some(val)),
|
||||
Failure(_) => Success(None),
|
||||
Forward(_) => Success(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ mod data;
|
|||
mod from_request;
|
||||
|
||||
pub use self::request::Request;
|
||||
pub use self::from_request::{FromRequest, RequestOutcome};
|
||||
pub use self::from_request::{FromRequest, Outcome};
|
||||
pub use self::param::{FromParam, FromSegments};
|
||||
pub use self::form::{Form, FromForm, FromFormValue, FormItems};
|
||||
pub use self::data::{Data, FromData, DataOutcome};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use response::{Responder, ResponseOutcome};
|
||||
use response::{Responder, Outcome};
|
||||
use http::hyper::{header, FreshHyperResponse};
|
||||
use http::mime::{Mime, TopLevel, SubLevel};
|
||||
use http::ContentType;
|
||||
|
@ -6,7 +6,7 @@ use http::ContentType;
|
|||
pub struct Content<T: Responder>(pub ContentType, pub T);
|
||||
|
||||
impl<T: Responder> Responder for Content<T> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||
res.headers_mut().set(header::ContentType(self.0.clone().into()));
|
||||
self.1.respond(res)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ macro_rules! impl_data_type_responder {
|
|||
pub struct $name<T: Responder>(pub T);
|
||||
|
||||
impl<T: Responder> Responder for $name<T> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||
let mime = Mime(TopLevel::$top, SubLevel::$sub, vec![]);
|
||||
res.headers_mut().set(header::ContentType(mime));
|
||||
self.0.respond(res)
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
use response::{ResponseOutcome, Responder};
|
||||
use http::hyper::{FreshHyperResponse, StatusCode};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Failure(pub StatusCode);
|
||||
|
||||
impl Responder for Failure {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
ResponseOutcome::forward(self.0, res)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
use std::convert::AsRef;
|
||||
|
||||
use response::{ResponseOutcome, Responder};
|
||||
use request::{Request, FromRequest, RequestOutcome};
|
||||
use outcome::IntoOutcome;
|
||||
use response::{self, Responder};
|
||||
use request::{self, Request, FromRequest};
|
||||
use http::hyper::{HyperSetCookie, HyperCookiePair, FreshHyperResponse};
|
||||
|
||||
const FLASH_COOKIE_NAME: &'static str = "_flash";
|
||||
|
@ -43,7 +44,7 @@ impl<R: Responder> Flash<R> {
|
|||
}
|
||||
|
||||
impl<R: Responder> Responder for Flash<R> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> response::Outcome<'b> {
|
||||
trace_!("Flash: setting message: {}:{}", self.name, self.message);
|
||||
res.headers_mut().set(HyperSetCookie(vec![self.cookie_pair()]));
|
||||
self.responder.respond(res)
|
||||
|
@ -73,7 +74,7 @@ impl Flash<()> {
|
|||
impl<'r> FromRequest<'r> for Flash<()> {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'r Request) -> RequestOutcome<Self, Self::Error> {
|
||||
fn from_request(request: &'r Request) -> request::Outcome<Self, Self::Error> {
|
||||
trace_!("Flash: attemping to retrieve message.");
|
||||
let r = request.cookies().find(FLASH_COOKIE_NAME).ok_or(()).and_then(|cookie| {
|
||||
// Clear the flash message.
|
||||
|
@ -92,6 +93,6 @@ impl<'r> FromRequest<'r> for Flash<()> {
|
|||
Ok(Flash::named(name, msg))
|
||||
});
|
||||
|
||||
RequestOutcome::of(r)
|
||||
r.into_outcome()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,66 +4,38 @@ mod with_status;
|
|||
mod flash;
|
||||
mod named_file;
|
||||
mod stream;
|
||||
mod failure;
|
||||
|
||||
pub mod data;
|
||||
|
||||
pub use self::responder::Responder;
|
||||
pub use self::responder::{Outcome, Responder};
|
||||
pub use self::redirect::Redirect;
|
||||
pub use self::with_status::StatusResponse;
|
||||
pub use self::flash::Flash;
|
||||
pub use self::named_file::NamedFile;
|
||||
pub use self::stream::Stream;
|
||||
pub use self::data::Content;
|
||||
pub use self::failure::Failure;
|
||||
pub use outcome::Outcome;
|
||||
|
||||
use outcome;
|
||||
use request::Data;
|
||||
use http::hyper::{StatusCode, FreshHyperResponse};
|
||||
use http::hyper::StatusCode;
|
||||
use outcome::Outcome::*;
|
||||
|
||||
pub type ResponseOutcome<'a> = Outcome<(), (), (StatusCode, FreshHyperResponse<'a>)>;
|
||||
|
||||
impl<'a> ResponseOutcome<'a> {
|
||||
#[inline(always)]
|
||||
pub fn of<A, B>(result: Result<A, B>) -> Self {
|
||||
match result {
|
||||
Ok(_) => Outcome::Success(()),
|
||||
Err(_) => Outcome::Failure(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn success() -> ResponseOutcome<'a> {
|
||||
Outcome::Success(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn failure() -> ResponseOutcome<'a> {
|
||||
Outcome::Failure(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn forward(s: StatusCode, r: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
Outcome::Forward((s, r))
|
||||
}
|
||||
}
|
||||
|
||||
pub type Response<'a> = Outcome<Box<Responder + 'a>, StatusCode, Data>;
|
||||
pub type Response<'a> = outcome::Outcome<Box<Responder + 'a>, StatusCode, Data>;
|
||||
|
||||
impl<'a> Response<'a> {
|
||||
#[inline(always)]
|
||||
pub fn success<T: Responder + 'a>(responder: T) -> Response<'a> {
|
||||
Outcome::Success(Box::new(responder))
|
||||
Success(Box::new(responder))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn failure(code: StatusCode) -> Response<'static> {
|
||||
Outcome::Failure(code)
|
||||
Failure(code)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn forward(data: Data) -> Response<'static> {
|
||||
Outcome::Forward(data)
|
||||
Forward(data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::io;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use response::{Responder, ResponseOutcome};
|
||||
use response::{Responder, Outcome};
|
||||
use http::hyper::{header, FreshHyperResponse};
|
||||
use http::ContentType;
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl NamedFile {
|
|||
}
|
||||
|
||||
impl Responder for NamedFile {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
if let Some(ext) = self.path().extension() {
|
||||
let ext_string = ext.to_string_lossy().to_lowercase();
|
||||
let content_type = ContentType::from_extension(&ext_string);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use response::{ResponseOutcome, Responder};
|
||||
use response::{Outcome, Responder};
|
||||
use http::hyper::{header, FreshHyperResponse, StatusCode};
|
||||
use outcome::IntoOutcome;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Redirect(StatusCode, String);
|
||||
|
@ -27,10 +28,10 @@ impl Redirect {
|
|||
}
|
||||
|
||||
impl<'a> Responder for Redirect {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||
res.headers_mut().set(header::ContentLength(0));
|
||||
res.headers_mut().set(header::Location(self.1.clone()));
|
||||
*(res.status_mut()) = self.0;
|
||||
ResponseOutcome::of(res.send(b""))
|
||||
res.send(b"").into_outcome()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,87 +2,86 @@ use std::io::{Read, Write};
|
|||
use std::fs::File;
|
||||
use std::fmt;
|
||||
|
||||
use response::ResponseOutcome;
|
||||
use http::mime::{Mime, TopLevel, SubLevel};
|
||||
use http::hyper::{header, FreshHyperResponse, StatusCode};
|
||||
use outcome::{self, IntoOutcome};
|
||||
use outcome::Outcome::*;
|
||||
|
||||
pub type Outcome<'a> = outcome::Outcome<(), (), (StatusCode, FreshHyperResponse<'a>)>;
|
||||
|
||||
// TODO: Have this return something saying whether every was okay. Need
|
||||
// something like to be able to forward requests on when things don't work out.
|
||||
// In particular, we want to try the next ranked route when when parsing
|
||||
// parameters doesn't work out.
|
||||
pub trait Responder {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> ResponseOutcome<'a>;
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a>;
|
||||
}
|
||||
|
||||
impl<'a> Responder for &'a str {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> Outcome<'b> {
|
||||
if res.headers().get::<header::ContentType>().is_none() {
|
||||
let mime = Mime(TopLevel::Text, SubLevel::Plain, vec![]);
|
||||
res.headers_mut().set(header::ContentType(mime));
|
||||
}
|
||||
|
||||
ResponseOutcome::of(res.send(self.as_bytes()))
|
||||
res.send(self.as_bytes()).into_outcome()
|
||||
}
|
||||
}
|
||||
|
||||
impl Responder for String {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
if res.headers().get::<header::ContentType>().is_none() {
|
||||
let mime = Mime(TopLevel::Text, SubLevel::Html, vec![]);
|
||||
res.headers_mut().set(header::ContentType(mime));
|
||||
}
|
||||
|
||||
ResponseOutcome::of(res.send(self.as_bytes()))
|
||||
res.send(self.as_bytes()).into_outcome()
|
||||
}
|
||||
}
|
||||
|
||||
impl Responder for File {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
let size = match self.metadata() {
|
||||
Ok(md) => md.len(),
|
||||
Err(e) => {
|
||||
error_!("Failed to read file metadata: {:?}", e);
|
||||
return ResponseOutcome::forward(StatusCode::InternalServerError, res);
|
||||
return Forward((StatusCode::InternalServerError, res));
|
||||
}
|
||||
};
|
||||
|
||||
let mut v = Vec::new();
|
||||
if let Err(e) = self.read_to_end(&mut v) {
|
||||
error_!("Failed to read file: {:?}", e);
|
||||
return ResponseOutcome::forward(StatusCode::InternalServerError, res);
|
||||
return Forward((StatusCode::InternalServerError, res));
|
||||
}
|
||||
|
||||
res.headers_mut().set(header::ContentLength(size));
|
||||
ResponseOutcome::of(res.start().and_then(|mut stream| stream.write_all(&v)))
|
||||
res.start().and_then(|mut stream| stream.write_all(&v)).into_outcome()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Responder> Responder for Option<T> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
if let Some(ref mut val) = *self {
|
||||
val.respond(res)
|
||||
} else {
|
||||
warn_!("Response was `None`.");
|
||||
ResponseOutcome::forward(StatusCode::NotFound, res)
|
||||
Forward((StatusCode::NotFound, res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Responder, E: fmt::Debug> Responder for Result<T, E> {
|
||||
// prepend with `default` when using impl specialization
|
||||
default fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
default fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
match *self {
|
||||
Ok(ref mut val) => val.respond(res),
|
||||
Err(ref e) => {
|
||||
error_!("{:?}", e);
|
||||
ResponseOutcome::forward(StatusCode::InternalServerError, res)
|
||||
Forward((StatusCode::InternalServerError, res))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Responder, E: Responder + fmt::Debug> Responder for Result<T, E> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
match *self {
|
||||
Ok(ref mut responder) => responder.respond(res),
|
||||
Err(ref mut responder) => responder.respond(res),
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use std::io::{Read, Write, ErrorKind};
|
||||
|
||||
use response::{Responder, ResponseOutcome};
|
||||
use response::{Responder, Outcome};
|
||||
use http::hyper::FreshHyperResponse;
|
||||
use outcome::Outcome::*;
|
||||
|
||||
// TODO: Support custom chunk sizes.
|
||||
/// The default size of each chunk in the streamed response.
|
||||
|
@ -26,12 +27,12 @@ impl<T: Read> Stream<T> {
|
|||
}
|
||||
|
||||
impl<T: Read> Responder for Stream<T> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
||||
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
||||
let mut stream = match res.start() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
error_!("Failed opening response stream: {:?}", e);
|
||||
return ResponseOutcome::failure();
|
||||
Err(ref err) => {
|
||||
error_!("Failed opening response stream: {:?}", err);
|
||||
return Failure(());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -46,22 +47,22 @@ impl<T: Read> Responder for Stream<T> {
|
|||
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
|
||||
Err(ref e) => {
|
||||
error_!("Error streaming response: {:?}", e);
|
||||
return ResponseOutcome::failure();
|
||||
return Failure(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = stream.write_all(&buffer[..read]) {
|
||||
error_!("Stream write_all() failed: {:?}", e);
|
||||
return ResponseOutcome::failure();
|
||||
return Failure(());
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = stream.end() {
|
||||
error_!("Stream end() failed: {:?}", e);
|
||||
return ResponseOutcome::failure();
|
||||
return Failure(());
|
||||
}
|
||||
|
||||
ResponseOutcome::success()
|
||||
Success(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use response::{Responder, ResponseOutcome};
|
||||
use response::{Responder, Outcome};
|
||||
use http::hyper::{StatusCode, FreshHyperResponse};
|
||||
|
||||
pub struct StatusResponse<R: Responder> {
|
||||
|
@ -16,7 +16,7 @@ impl<R: Responder> StatusResponse<R> {
|
|||
}
|
||||
|
||||
impl<R: Responder> Responder for StatusResponse<R> {
|
||||
fn respond<'b>(&mut self, mut res: FreshHyperResponse<'b>) -> ResponseOutcome<'b> {
|
||||
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