mirror of https://github.com/rwf2/Rocket.git
parent
63d31e8082
commit
d4f9525b22
|
@ -2,10 +2,50 @@ use utils::*;
|
|||
use ::{CATCH_STRUCT_PREFIX, CATCH_FN_PREFIX};
|
||||
|
||||
use syntax::codemap::{Span};
|
||||
use syntax::ast::{MetaItem};
|
||||
use syntax::ast::{MetaItem, Ident, TyKind};
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::parse::token::{self, str_to_ident};
|
||||
use parser::ErrorParams;
|
||||
|
||||
const ERR_PARAM: &'static str = "_error";
|
||||
const REQ_PARAM: &'static str = "_request";
|
||||
|
||||
trait ErrorGenerateExt {
|
||||
fn generate_fn_arguments(&self, &ExtCtxt, Ident, Ident) -> Vec<TokenTree>;
|
||||
}
|
||||
|
||||
impl ErrorGenerateExt for ErrorParams {
|
||||
fn generate_fn_arguments(&self, ecx: &ExtCtxt, err: Ident, req: Ident)
|
||||
-> Vec<TokenTree> {
|
||||
let arg_help = "error handlers can take either a `rocket::Error` or \
|
||||
`rocket::Request` type, or both.";
|
||||
|
||||
// Retrieve the params from the user's handler and check the number.
|
||||
let input_args = &self.annotated_fn.decl().inputs;
|
||||
if input_args.len() > 2 {
|
||||
let sp = self.annotated_fn.span();
|
||||
ecx.struct_span_err(sp, "error handlers can have at most 2 arguments")
|
||||
.help(arg_help).emit()
|
||||
}
|
||||
|
||||
// (Imperfectly) inspect the types to figure which params to pass in.
|
||||
let args = input_args.iter().map(|arg| &arg.ty).filter_map(|ty| {
|
||||
match ty.node {
|
||||
TyKind::Rptr(..) => Some(req.clone()),
|
||||
TyKind::Path(..) => Some(err.clone()),
|
||||
_ => {
|
||||
ecx.struct_span_err(ty.span, "unexpected error handler argument")
|
||||
.help(arg_help).emit();
|
||||
None
|
||||
}
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
sep_by_tok(ecx, &args, token::Comma)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
|
||||
annotated: &Annotatable, push: &mut FnMut(Annotatable)) {
|
||||
let error = ErrorParams::from(ecx, sp, meta_item, annotated);
|
||||
|
@ -13,11 +53,14 @@ pub fn error_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
|
|||
let user_fn_name = error.annotated_fn.ident();
|
||||
let catch_fn_name = user_fn_name.prepend(CATCH_FN_PREFIX);
|
||||
let code = error.code.node;
|
||||
let (err_ident, req_ident) = (str_to_ident(ERR_PARAM), str_to_ident(REQ_PARAM));
|
||||
let fn_arguments = error.generate_fn_arguments(ecx, err_ident, req_ident);
|
||||
|
||||
emit_item(push, quote_item!(ecx,
|
||||
fn $catch_fn_name<'rocket>(err: ::rocket::Error,
|
||||
req: &'rocket ::rocket::Request<'rocket>)
|
||||
fn $catch_fn_name<'rocket>($err_ident: ::rocket::Error,
|
||||
$req_ident: &'rocket ::rocket::Request<'rocket>)
|
||||
-> ::rocket::Response<'rocket> {
|
||||
let result = $user_fn_name(err, req);
|
||||
let result = $user_fn_name($fn_arguments);
|
||||
rocket::Response::with_raw_status($code, result)
|
||||
}
|
||||
).expect("catch function"));
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#![feature(plugin)]
|
||||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate rocket;
|
||||
|
||||
use rocket::{Error, Request};
|
||||
|
||||
#[error(404)]
|
||||
fn err_a(_a: Error, _b: Request, _c: Error) -> &'static str { "hi" }
|
||||
//~^ ERROR: can have at most 2
|
||||
|
||||
#[error(404)]
|
||||
fn err_b(_a: (isize, usize)) -> &'static str { "hi" }
|
||||
//~^ ERROR: unexpected error handler argument
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#![feature(plugin)]
|
||||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate rocket;
|
||||
|
||||
use rocket::{Error, Request};
|
||||
|
||||
#[error(404)]
|
||||
fn err0() -> &'static str { "hi" }
|
||||
|
||||
#[error(404)]
|
||||
fn err1a(_err: Error) -> &'static str { "hi" }
|
||||
|
||||
#[error(404)]
|
||||
fn err1b(_req: &Request) -> &'static str { "hi" }
|
||||
|
||||
#[error(404)]
|
||||
fn err2(_err: Error, _req: &Request) -> &'static str { "hi" }
|
||||
|
||||
fn main() {
|
||||
rocket::ignite()
|
||||
.catch(errors![err0, err1a, err1b, err2]);
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate rocket;
|
||||
use rocket::{Error, Request};
|
||||
|
||||
#[get("/hello/<name>/<age>")]
|
||||
fn hello(name: &str, age: i8) -> String {
|
||||
|
@ -10,10 +9,10 @@ fn hello(name: &str, age: i8) -> String {
|
|||
}
|
||||
|
||||
#[error(404)]
|
||||
fn not_found<'r>(_error: Error, request: &'r Request<'r>) -> String {
|
||||
fn not_found(req: &rocket::Request) -> String {
|
||||
format!("<p>Sorry, but '{}' is not a valid path!</p>
|
||||
<p>Try visiting /hello/<name>/<age> instead.</p>",
|
||||
request.uri)
|
||||
req.uri)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
pub enum Error {
|
||||
BadMethod,
|
||||
BadParse,
|
||||
NoRoute, // FIXME: Add a chain of routes attempted.
|
||||
NoRoute, // TODO: Add a chain of routes attempted.
|
||||
Internal,
|
||||
NoKey,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue