Fix get_raw_segments index argument in route codegen.

Fixes #41.
This commit is contained in:
Sergio Benitez 2016-12-24 11:58:24 -08:00
parent 14f79c3733
commit 9cebab5037
2 changed files with 58 additions and 4 deletions

View File

@ -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 {
@ -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();

View File

@ -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)));
}
}