diff --git a/Cargo.toml b/Cargo.toml index d567a94e..22c3b6b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,5 @@ members = [ "examples/content_types", "examples/hello_ranks", "examples/testing", + "examples/from_request", ] diff --git a/examples/from_request/Cargo.toml b/examples/from_request/Cargo.toml new file mode 100644 index 00000000..820493f4 --- /dev/null +++ b/examples/from_request/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "from_request" +version = "0.0.1" +authors = ["Sergio Benitez "] +workspace = "../../" + +[dependencies] +rocket = { path = "../../lib" } +rocket_macros = { path = "../../macros" } diff --git a/examples/from_request/src/main.rs b/examples/from_request/src/main.rs new file mode 100644 index 00000000..ad2cf3e4 --- /dev/null +++ b/examples/from_request/src/main.rs @@ -0,0 +1,33 @@ +#![feature(plugin)] +#![plugin(rocket_macros)] + +extern crate rocket; + +use std::fmt; +use rocket::Rocket; +use rocket::request::{Request, FromRequest}; + +#[derive(Debug)] +struct HeaderCount(usize); + +impl fmt::Display for HeaderCount { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl<'r, 'c> FromRequest<'r, 'c> for HeaderCount { + type Error = (); + fn from_request(request: &'r Request<'c>) -> Result { + Ok(HeaderCount(request.headers().len())) + } +} + +#[get("/")] +fn header_count(header_count: HeaderCount) -> String { + format!("Your request contained {} headers!", header_count) +} + +fn main() { + Rocket::new("localhost", 8000).mount_and_launch("/", routes![header_count]); +} diff --git a/macros/src/decorators/route.rs b/macros/src/decorators/route.rs index bf116336..faba22da 100644 --- a/macros/src/decorators/route.rs +++ b/macros/src/decorators/route.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use ::{ROUTE_STRUCT_PREFIX, ROUTE_FN_PREFIX}; +use ::{ROUTE_STRUCT_PREFIX, ROUTE_FN_PREFIX, PARAM_PREFIX}; use utils::{emit_item, span, sep_by_tok, SpanExt, IdentExt, ArgExt, option_as_expr}; use parser::RouteParams; @@ -67,7 +67,7 @@ impl RouteGenerateExt for RouteParams { } let arg = arg.unwrap(); - let (name, ty) = (arg.ident().unwrap(), &arg.ty); + let (name, ty) = (arg.ident().unwrap().prepend(PARAM_PREFIX), &arg.ty); Some(quote_stmt!(ecx, let $name: $ty = if let Ok(s) = ::std::str::from_utf8(_req.data.as_slice()) { @@ -107,7 +107,7 @@ impl RouteGenerateExt for RouteParams { // Generate code for each user declared parameter. for (i, arg) in all.iter().filter(declared).enumerate() { - let (ident, ty) = (arg.ident().unwrap(), &arg.ty); + let (ident, ty) = (arg.ident().unwrap().prepend(PARAM_PREFIX), &arg.ty); fn_param_statements.push(quote_stmt!(ecx, let $ident: $ty = match _req.get_param($i) { Ok(v) => v, @@ -125,7 +125,7 @@ impl RouteGenerateExt for RouteParams { // Generate the code for `form_request` parameters. for arg in all.iter().filter(from_request) { - let (ident, ty) = (arg.ident().unwrap(), &arg.ty); + let (ident, ty) = (arg.ident().unwrap().prepend(PARAM_PREFIX), &arg.ty); fn_param_statements.push(quote_stmt!(ecx, let $ident: $ty = match <$ty as ::rocket::request::FromRequest>::from_request(&_req) { @@ -140,7 +140,7 @@ impl RouteGenerateExt for RouteParams { fn generate_fn_arguments(&self, ecx: &ExtCtxt) -> Vec { let args = self.annotated_fn.decl().inputs.iter().map(|a| { - a.ident().expect("function decl pat -> ident").clone() + a.ident().expect("function decl pat -> ident").prepend(PARAM_PREFIX) }).collect::>(); sep_by_tok(ecx, &args, token::Comma) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a5461c82..e573e8a1 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -21,6 +21,7 @@ use rustc_plugin::Registry; use syntax::ext::base::SyntaxExtension; use syntax::parse::token::intern; +const PARAM_PREFIX: &'static str = "rocket_param_"; const ROUTE_STRUCT_PREFIX: &'static str = "static_rocket_route_info_for_"; const CATCH_STRUCT_PREFIX: &'static str = "static_rocket_catch_info_for_"; const ROUTE_FN_PREFIX: &'static str = "rocket_route_fn_";