Rename Response::new to complete. Add Response::failure using newly added Failure response.

This commit is contained in:
Sergio Benitez 2016-10-08 20:53:04 -07:00
parent 6275e576b5
commit 619b1d787e
10 changed files with 72 additions and 20 deletions

View File

@ -172,7 +172,8 @@ fn from_form_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substruct
$ident = match ::rocket::request::FromFormValue::from_form_value(v) { $ident = match ::rocket::request::FromFormValue::from_form_value(v) {
Ok(v) => Some(v), Ok(v) => Some(v),
Err(e) => { Err(e) => {
println!("\tError parsing form val '{}': {:?}", $id_str, e); println!(" => Error parsing form val '{}': {:?}",
$id_str, e);
$return_err_stmt $return_err_stmt
} }
}; };
@ -187,7 +188,8 @@ fn from_form_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substruct
match k { match k {
$arms $arms
_ => { _ => {
println!("\t{}={} has no matching field in struct.", k, v); println!(" => {}={} has no matching field in struct.",
k, v);
$return_err_stmt $return_err_stmt
} }
}; };
@ -206,7 +208,7 @@ fn from_form_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substruct
failure_conditions.push(quote_tokens!(cx, failure_conditions.push(quote_tokens!(cx,
if $ident.is_none() && if $ident.is_none() &&
<$ty as ::rocket::request::FromFormValue>::default().is_none() { <$ty as ::rocket::request::FromFormValue>::default().is_none() {
println!("\t'{}' did not parse.", stringify!($ident)); println!(" => '{}' did not parse.", stringify!($ident));
true true
} else { false } } else { false }
)); ));

View File

@ -94,8 +94,11 @@ impl RouteGenerateExt for RouteParams {
let expr = quote_expr!(ecx, let expr = quote_expr!(ecx,
match ::std::str::from_utf8(_req.data.as_slice()) { match ::std::str::from_utf8(_req.data.as_slice()) {
Ok(s) => s, Ok(s) => s,
Err(_) => return ::rocket::Response::new( Err(_) => {
::rocket::response::Empty::bad_request("form isn't utf8")) println!(" => Form is not valid UTF8.");
return ::rocket::Response::failed(
::rocket::http::StatusCode::BadRequest);
}
} }
); );
@ -226,7 +229,7 @@ fn generic_route_decorator(known_method: Option<Spanned<Method>>,
$query_statement $query_statement
$param_statements $param_statements
let result = $user_fn_name($fn_arguments); let result = $user_fn_name($fn_arguments);
::rocket::Response::new(result) ::rocket::Response::complete(result)
} }
).unwrap()); ).unwrap());

View File

@ -1,6 +1,10 @@
extern crate rocket; extern crate rocket;
use std::io;
use std::fs::File;
use rocket::{Request, Response, Route, Data}; use rocket::{Request, Response, Route, Data};
use rocket::http::StatusCode;
use rocket::request::FromParam; use rocket::request::FromParam;
use rocket::http::Method::*; use rocket::http::Method::*;
@ -9,17 +13,35 @@ fn forward(_req: &Request, data: Data) -> Response<'static> {
} }
fn hi(_req: &Request, _: Data) -> Response<'static> { fn hi(_req: &Request, _: Data) -> Response<'static> {
Response::new("Hello!") Response::complete("Hello!")
} }
fn name<'a>(req: &'a Request, _: Data) -> Response<'a> { fn name<'a>(req: &'a Request, _: Data) -> Response<'a> {
Response::new(req.get_param(0).unwrap_or("unnamed")) Response::complete(req.get_param(0).unwrap_or("unnamed"))
} }
#[allow(dead_code)]
fn echo_url<'a>(req: &'a Request, _: Data) -> Response<'a> { fn echo_url<'a>(req: &'a Request, _: Data) -> Response<'a> {
let param = req.uri().as_str().split_at(6).1; let param = req.uri().as_str().split_at(6).1;
Response::new(String::from_param(param)) Response::complete(String::from_param(param))
}
fn upload(req: &Request, data: Data) -> Response {
if !req.content_type().is_text() {
return Response::failed(StatusCode::BadRequest);
}
let file = File::create("upload.txt");
if let Ok(mut file) = file {
if io::copy(&mut data.open(), &mut file).is_ok() {
return Response::complete("Upload successful.");
}
println!(" => Failed copying.");
Response::failed(StatusCode::InternalServerError)
} else {
println!(" => Couldn't open file: {:?}", file.unwrap_err());
Response::failed(StatusCode::InternalServerError)
}
} }
fn main() { fn main() {
@ -28,9 +50,10 @@ fn main() {
let echo = Route::new(Get, "/", echo_url); let echo = Route::new(Get, "/", echo_url);
let name = Route::new(Get, "/<name>", name); let name = Route::new(Get, "/<name>", name);
let upload_route = Route::new(Post, "/upload", upload);
rocket::ignite() rocket::ignite()
.mount("/", vec![always_forward, hello]) .mount("/", vec![always_forward, hello, upload_route])
.mount("/hello", vec![name.clone()]) .mount("/hello", vec![name.clone()])
.mount("/hi", vec![name]) .mount("/hi", vec![name])
.mount("/echo:<str>", vec![echo]) .mount("/echo:<str>", vec![echo])

View File

View File

@ -79,6 +79,9 @@ impl ContentType {
} }
} }
/// Returns true if the content type is plain text, i.e.: `text/plain`.
is_some!(is_text: Text/Plain);
/// Returns true if the content type is JSON, i.e: `application/json`. /// Returns true if the content type is JSON, i.e: `application/json`.
is_some!(json, is_json: Application/Json); is_some!(json, is_json: Application/Json);

View File

@ -1,7 +1,4 @@
use std::io::{BufRead, Read, Cursor, BufReader}; use std::io::{BufRead, Read, Cursor, BufReader};
use std::net::TcpStream;
use request::Request;
pub struct Data { pub struct Data {
stream: Cursor<Vec<u8>>, stream: Cursor<Vec<u8>>,
@ -9,11 +6,11 @@ pub struct Data {
} }
impl Data { impl Data {
fn open(self) -> impl BufRead { pub fn open(self) -> impl BufRead {
Cursor::new(self.buffer).chain(BufReader::new(self.stream)) Cursor::new(self.buffer).chain(BufReader::new(self.stream))
} }
fn peek(&self) -> &[u8] { pub fn peek(&self) -> &[u8] {
&self.buffer &self.buffer
} }

View File

@ -0,0 +1,17 @@
use response::{ResponseOutcome, Outcome, Responder};
use http::hyper::{FreshHyperResponse, StatusCode};
pub struct Failure(StatusCode);
impl Failure {
#[inline(always)]
pub fn new(status: StatusCode) -> Failure {
Failure(status)
}
}
impl Responder for Failure {
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
Outcome::Forward((self.0, res))
}
}

View File

@ -5,6 +5,7 @@ mod with_status;
mod flash; mod flash;
mod named_file; mod named_file;
mod stream; mod stream;
mod failure;
pub mod data; pub mod data;
@ -16,6 +17,7 @@ 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;
pub use self::data::Content; pub use self::data::Content;
pub use self::failure::Failure;
pub use outcome::Outcome; pub use outcome::Outcome;
use std::fmt; use std::fmt;
@ -33,7 +35,7 @@ pub enum Response<'a> {
impl<'a> Response<'a> { impl<'a> Response<'a> {
#[inline(always)] #[inline(always)]
pub fn new<T: Responder + 'a>(body: T) -> Response<'a> { pub fn complete<T: Responder + 'a>(body: T) -> Response<'a> {
Response::Complete(Box::new(body)) Response::Complete(Box::new(body))
} }
@ -42,10 +44,15 @@ impl<'a> Response<'a> {
Response::Forward(data) Response::Forward(data)
} }
#[inline(always)]
pub fn failed(code: StatusCode) -> Response<'static> {
Response::complete(Failure::new(code))
}
#[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::new(StatusResponse::new(status_code, body)) Response::complete(StatusResponse::new(status_code, body))
} }
#[doc(hidden)] #[doc(hidden)]

View File

@ -60,7 +60,7 @@ mod tests {
type SimpleRoute = (Method, &'static str); type SimpleRoute = (Method, &'static str);
fn dummy_handler(_req: &Request, _: Data) -> Response<'static> { fn dummy_handler(_req: &Request, _: Data) -> Response<'static> {
Response::new("hi") Response::complete("hi")
} }
fn m_collide(a: SimpleRoute, b: SimpleRoute) -> bool { fn m_collide(a: SimpleRoute, b: SimpleRoute) -> bool {

View File

@ -75,7 +75,7 @@ mod test {
use {Response, Request, Data}; use {Response, Request, Data};
fn dummy_handler(_req: &Request, _: Data) -> Response<'static> { fn dummy_handler(_req: &Request, _: Data) -> Response<'static> {
Response::new("hi") Response::complete("hi")
} }
fn router_with_routes(routes: &[&'static str]) -> Router { fn router_with_routes(routes: &[&'static str]) -> Router {