Skip to content

Commit

Permalink
Fix get_raw_segments index argument in route codegen.
Browse files Browse the repository at this point in the history
Fixes #41.
  • Loading branch information
SergioBenitez committed Dec 24, 2016
1 parent 14f79c3 commit 9cebab5
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
17 changes: 13 additions & 4 deletions codegen/src/decorators/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use syntax::parse::token;
use syntax::ptr::P;

use rocket::http::{Method, ContentType};
use rocket::http::uri::URI;

fn method_to_path(ecx: &ExtCtxt, method: Method) -> Path {
quote_enum!(ecx, method => ::rocket::http::Method {
Expand Down Expand Up @@ -136,10 +137,18 @@ impl RouteGenerateExt for RouteParams {
Some(s) => <$ty as ::rocket::request::FromParam>::from_param(s),
None => return ::rocket::Outcome::Forward(_data)
}),
Param::Many(_) => quote_expr!(ecx, match _req.get_raw_segments($i) {
Some(s) => <$ty as ::rocket::request::FromSegments>::from_segments(s),
None => return ::rocket::Outcome::forward(_data)
}),
Param::Many(_) => {
// Determine the index the dynamic segments parameter begins.
let d = URI::new(self.path.node.as_str()).segments().enumerate()
.filter(|&(_, s)| s.starts_with("<"))
.map((&|(d, _)| d))
.next().expect("segment when segment is iterated");

quote_expr!(ecx, match _req.get_raw_segments($d) {
Some(s) => <$ty as ::rocket::request::FromSegments>::from_segments(s),
None => return ::rocket::Outcome::forward(_data)
})
},
};

let original_ident = param.ident();
Expand Down
45 changes: 45 additions & 0 deletions lib/tests/segments-issue-41.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

use std::path::PathBuf;

#[get("/test/<path..>")]
fn test(path: PathBuf) -> String {
format!("{:?}", path)
}

#[get("/two/<path..>")]
fn two(path: PathBuf) -> String {
format!("{:?}", path)
}

#[get("/one/two/<path..>")]
fn one_two(path: PathBuf) -> String {
format!("{:?}", path)
}

#[get("/<path..>", rank = 2)]
fn none(path: PathBuf) -> String {
format!("{:?}", path)
}

use rocket::testing::MockRequest;
use rocket::http::Method::*;

#[test]
fn segments_works() {
let rocket = rocket::ignite().mount("/", routes![test, two, one_two, none]);

// We construct a path that matches each of the routes above. We ensure the
// prefix is stripped, confirming that dynamic segments are working.
for prefix in &["", "/test", "/two", "/one/two"] {
let path = "this/is/the/path/we/want";
let mut req = MockRequest::new(Get, format!("{}/{}", prefix, path));

let mut response = req.dispatch_with(&rocket);
let body_str = response.body().and_then(|b| b.into_string());
assert_eq!(body_str, Some(format!("{:?}", path)));
}
}

0 comments on commit 9cebab5

Please sign in to comment.