Rename `data` to `content` in `response`. Remove `DataOutcome`.

This commit is contained in:
Sergio Benitez 2016-10-25 13:03:50 +02:00
parent 0a4a647829
commit f5a5ea3a22
17 changed files with 127 additions and 122 deletions

View File

@ -4,9 +4,9 @@ extern crate serde_json;
use std::ops::{Deref, DerefMut};
use std::io::Read;
use rocket::Outcome::*;
use rocket::request::{Request, Data, FromData, DataOutcome};
use rocket::response::{self, Responder, data};
use rocket::outcome::{Outcome, IntoOutcome};
use rocket::request::{data, Request, Data, FromData};
use rocket::response::{self, Responder, content};
use rocket::http::StatusCode;
use rocket::http::hyper::FreshHyperResponse;
@ -71,24 +71,24 @@ const MAX_SIZE: u64 = 1048576;
impl<T: Deserialize> FromData for JSON<T> {
type Error = SerdeError;
fn from_data(request: &Request, data: Data) -> DataOutcome<Self, SerdeError> {
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, SerdeError> {
if !request.content_type().is_json() {
error_!("Content-Type is not JSON.");
return DataOutcome::forward(data);
return Outcome::Forward(data);
}
let reader = data.open().take(MAX_SIZE);
DataOutcome::of(serde_json::from_reader(reader).map(|val| JSON(val)))
serde_json::from_reader(reader).map(|val| JSON(val)).into_outcome()
}
}
impl<T: Serialize> Responder for JSON<T> {
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),
Ok(json_string) => content::JSON(json_string).respond(res),
Err(e) => {
error_!("JSON failed to serialize: {:?}", e);
Forward((StatusCode::BadRequest, res))
Outcome::Forward((StatusCode::BadRequest, res))
}
}
}

View File

@ -17,10 +17,10 @@ use std::path::{Path, PathBuf};
use std::collections::HashMap;
use rocket::config;
use rocket::response::{Content, Outcome, Responder};
use rocket::response::{self, Content, Responder};
use rocket::http::hyper::FreshHyperResponse;
use rocket::http::{ContentType, StatusCode};
use rocket::Outcome::*;
use rocket::Outcome;
/// The Template type implements generic support for template rendering in
/// Rocket.
@ -160,7 +160,7 @@ impl Template {
}
impl Responder for Template {
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> response::Outcome<'a> {
let content_type = match self.1 {
Some(ref ext) => ContentType::from_extension(ext),
None => ContentType::html()
@ -168,7 +168,7 @@ impl Responder for Template {
match self.0 {
Some(ref render) => Content(content_type, render.as_str()).respond(res),
None => Forward((StatusCode::InternalServerError, res)),
None => Outcome::Forward((StatusCode::InternalServerError, res)),
}
}
}

View File

@ -7,7 +7,7 @@ extern crate serde_json;
use rocket::{Request, Error};
use rocket::http::ContentType;
use rocket::response::data;
use rocket::response::content::JSON;
#[derive(Debug, Serialize, Deserialize)]
struct Person {
@ -15,15 +15,17 @@ struct Person {
age: i8,
}
// This shows how to manually serialize some JSON, but in a real application,
// we'd use the JSON contrib type.
#[get("/<name>/<age>", format = "application/json")]
fn hello(content_type: ContentType, name: String, age: i8) -> data::JSON<String> {
fn hello(content_type: ContentType, name: String, age: i8) -> JSON<String> {
let person = Person {
name: name,
age: age,
};
println!("ContentType: {}", content_type);
data::JSON(serde_json::to_string(&person).unwrap())
JSON(serde_json::to_string(&person).unwrap())
}
#[error(404)]

View File

@ -6,7 +6,7 @@ extern crate rocket;
use std::io;
use rocket::request::Data;
use rocket::response::data::Plain;
use rocket::response::content::Plain;
#[post("/upload", format = "text/plain", data = "<data>")]
fn upload(data: Data) -> io::Result<Plain<String>> {

View File

@ -3,7 +3,7 @@
extern crate rocket;
use rocket::response::{data, Stream};
use rocket::response::{content, Stream};
use std::io::{self, repeat, Repeat, Read, Take};
use std::fs::File;
@ -11,8 +11,8 @@ use std::fs::File;
type LimitedRepeat = Take<Repeat>;
#[get("/")]
fn root() -> data::Plain<Stream<LimitedRepeat>> {
data::Plain(Stream::from(repeat('a' as u8).take(25000)))
fn root() -> content::Plain<Stream<LimitedRepeat>> {
content::Plain(Stream::from(repeat('a' as u8).take(25000)))
}
#[get("/big_file")]

View File

@ -74,7 +74,7 @@ macro_rules! default_errors {
$(
fn $fn_name<'r>(_: Error, _r: &'r Request) -> Response<'r> {
Response::with_raw_status($code,
data::HTML(error_page_template!($code, $name, $description))
content::HTML(error_page_template!($code, $name, $description))
)
}
@ -91,7 +91,7 @@ pub mod defaults {
use std::collections::HashMap;
use request::Request;
use response::{Response, data};
use response::{Response, content};
use error::Error;
pub fn get() -> HashMap<u16, Catcher> {

View File

@ -86,7 +86,6 @@ 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`).
@ -101,28 +100,11 @@ pub enum Outcome<S, E, F> {
Forward(F),
}
/// Conversion trait from some type into an Outcome type.
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.
///

View File

@ -1,33 +1,18 @@
use outcome::Outcome;
use outcome::{self, IntoOutcome};
use outcome::Outcome::*;
use http::StatusCode;
use request::{Request, Data};
/// Type alias for the `Outcome` of a `FromData` conversion.
pub type DataOutcome<S, E> = Outcome<S, (StatusCode, E), Data>;
pub type Outcome<S, E> = outcome::Outcome<S, (StatusCode, E), Data>;
impl<S, E> DataOutcome<S, E> {
#[inline(always)]
pub fn of(result: Result<S, E>) -> Self {
match result {
Ok(val) => DataOutcome::success(val),
Err(err) => DataOutcome::failure(StatusCode::InternalServerError, err)
impl<'a, S, E> IntoOutcome<S, (StatusCode, E), Data> for Result<S, E> {
fn into_outcome(self) -> Outcome<S, E> {
match self {
Ok(val) => Success(val),
Err(err) => Failure((StatusCode::InternalServerError, err))
}
}
#[inline(always)]
pub fn success(s: S) -> Self {
Outcome::Success(s)
}
#[inline(always)]
pub fn failure(status: StatusCode, e: E) -> Self {
Outcome::Failure((status, e))
}
#[inline(always)]
pub fn forward(data: Data) -> Self {
Outcome::Forward(data)
}
}
/// Trait used to derive an object from incoming request data.
@ -75,25 +60,25 @@ pub trait FromData: Sized {
/// If the parse is successful, an outcome of `Success` is returned. If the
/// data does not correspond to the type of `Self`, `Forward` is returned.
/// If parsing fails, `Failure` is returned.
fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error>;
fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error>;
}
/// The identity implementation of `FromData`. Always returns `Success`.
impl FromData for Data {
type Error = ();
fn from_data(_: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
DataOutcome::success(data)
fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
Success(data)
}
}
impl<T: FromData> FromData for Result<T, T::Error> {
type Error = ();
fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
match T::from_data(request, data) {
Outcome::Success(val) => DataOutcome::success(Ok(val)),
Outcome::Failure((_, val)) => DataOutcome::success(Err(val)),
Outcome::Forward(data) => DataOutcome::forward(data),
Success(val) => Success(Ok(val)),
Failure((_, val)) => Success(Err(val)),
Forward(data) => Forward(data),
}
}
}
@ -101,11 +86,11 @@ impl<T: FromData> FromData for Result<T, T::Error> {
impl<T: FromData> FromData for Option<T> {
type Error = ();
fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
match T::from_data(request, data) {
Outcome::Success(val) => DataOutcome::success(Some(val)),
Outcome::Failure(_) => DataOutcome::success(None),
Outcome::Forward(_) => DataOutcome::success(None)
Success(val) => Success(Some(val)),
Failure(_) => Success(None),
Forward(_) => Success(None)
}
}
}

View File

@ -5,7 +5,7 @@
#[cfg(not(any(test, feature = "testing")))] pub mod data_stream;
mod from_data;
pub use self::from_data::{FromData, DataOutcome};
pub use self::from_data::{FromData, Outcome};
#[cfg(any(test, feature = "testing"))] pub use self::test_data::Data;
#[cfg(not(any(test, feature = "testing")))] pub use self::data::Data;

View File

@ -28,7 +28,8 @@ use std::fmt::{self, Debug};
use std::io::Read;
use http::StatusCode;
use request::{Request, FromData, Data, DataOutcome};
use request::{data, Request, FromData, Data};
use outcome::Outcome::*;
// TODO: This works and is safe, but the lifetime appears twice.
/// A `FromData` type for parsing `FromForm` types.
@ -230,23 +231,23 @@ impl<'f, T: FromForm<'f> + Debug + 'f> Debug for Form<'f, T> {
impl<'f, T: FromForm<'f>> FromData for Form<'f, T> where T::Error: Debug {
type Error = Option<String>;
fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
if !request.content_type().is_form() {
warn_!("Form data does not have form content type.");
return DataOutcome::forward(data);
return Forward(data);
}
let mut form_string = String::with_capacity(4096);
let mut stream = data.open().take(32768);
if let Err(e) = stream.read_to_string(&mut form_string) {
error_!("IO Error: {:?}", e);
DataOutcome::failure(StatusCode::InternalServerError, None)
Failure((StatusCode::InternalServerError, None))
} else {
match Form::new(form_string) {
Ok(form) => DataOutcome::success(form),
Ok(form) => Success(form),
Err((form_string, e)) => {
error_!("Failed to parse value from form: {:?}", e);
DataOutcome::failure(StatusCode::BadRequest, Some(form_string))
Failure((StatusCode::BadRequest, Some(form_string)))
}
}
}

View File

@ -1,6 +1,6 @@
use std::fmt::Debug;
use outcome;
use outcome::{self, IntoOutcome};
use request::Request;
use outcome::Outcome::*;
use http::{StatusCode, ContentType, Method, Cookies};
@ -8,6 +8,15 @@ use http::{StatusCode, ContentType, Method, Cookies};
/// Type alias for the `Outcome` of a `FromRequest` conversion.
pub type Outcome<T, E> = outcome::Outcome<T, (StatusCode, E), ()>;
impl<T, E> IntoOutcome<T, (StatusCode, E), ()> for Result<T, E> {
fn into_outcome(self) -> Outcome<T, E> {
match self {
Ok(val) => Success(val),
Err(val) => Failure((StatusCode::BadRequest, val))
}
}
}
pub trait FromRequest<'r>: Sized {
type Error: Debug;

View File

@ -17,11 +17,12 @@
mod request;
mod param;
mod form;
mod data;
mod from_request;
pub mod data;
pub use self::request::Request;
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};
pub use self::data::{Data, FromData};

View File

@ -0,0 +1,12 @@
use outcome::Outcome;
use response::{self, 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>) -> response::Outcome<'a> {
Outcome::Forward((self.0, res))
}
}

View File

@ -4,49 +4,17 @@ mod with_status;
mod flash;
mod named_file;
mod stream;
mod response;
mod failure;
pub mod data;
pub mod content;
pub use self::response::Response;
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;
use outcome;
use request::Data;
use http::hyper::StatusCode;
use outcome::Outcome::*;
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> {
Success(Box::new(responder))
}
#[inline(always)]
pub fn failure(code: StatusCode) -> Response<'static> {
Failure(code)
}
#[inline(always)]
pub fn forward(data: Data) -> Response<'static> {
Forward(data)
}
#[inline(always)]
pub fn with_raw_status<T: Responder + 'a>(status: u16, body: T) -> Response<'a> {
let status_code = StatusCode::from_u16(status);
Response::success(StatusResponse::new(status_code, body))
}
#[doc(hidden)]
#[inline(always)]
pub fn responder(self) -> Option<Box<Responder + 'a>> {
self.succeeded()
}
}
pub use self::content::Content;
pub use self::failure::Failure;

View File

@ -9,6 +9,16 @@ use outcome::Outcome::*;
pub type Outcome<'a> = outcome::Outcome<(), (), (StatusCode, FreshHyperResponse<'a>)>;
impl<'a, T, E> IntoOutcome<(), (), (StatusCode, FreshHyperResponse<'a>)> for Result<T, E> {
fn into_outcome(self) -> Outcome<'a> {
match self {
Ok(_) => Success(()),
Err(_) => Failure(())
}
}
}
pub trait Responder {
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a>;
}

View File

@ -0,0 +1,35 @@
use request::Data;
use outcome::{self, Outcome};
use http::hyper::StatusCode;
use response::{Responder, StatusResponse};
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))
}
#[inline(always)]
pub fn failure(code: StatusCode) -> Response<'static> {
Outcome::Failure(code)
}
#[inline(always)]
pub fn forward(data: Data) -> Response<'static> {
Outcome::Forward(data)
}
#[inline(always)]
pub fn with_raw_status<T: Responder + 'a>(status: u16, body: T) -> Response<'a> {
let status_code = StatusCode::from_u16(status);
Response::success(StatusResponse::new(status_code, body))
}
#[doc(hidden)]
#[inline(always)]
pub fn responder(self) -> Option<Box<Responder + 'a>> {
self.succeeded()
}
}