Remove RequestOutcome, ResponseOutcome in favor of Outcome. Remove Failure response type.

This commit is contained in:
Sergio Benitez 2016-10-25 11:17:49 +02:00
parent 6a6efaf56b
commit 5447f81f77
16 changed files with 128 additions and 160 deletions

View File

@ -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))
}
}
}

View File

@ -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)),
}
}
}

View File

@ -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()))
}
}

View File

@ -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 {

View File

@ -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"),
}
}
}

View File

@ -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),
}
}
}

View File

@ -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};

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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()
}
}

View File

@ -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)]

View File

@ -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);

View File

@ -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()
}
}

View File

@ -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),

View File

@ -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(())
}
}

View File

@ -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)
}