From 4e0b37d18e77186e05893e7d8c54c2a50ea13472 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Fri, 6 Mar 2015 23:48:04 +0000 Subject: [PATCH] fix(router): reintroduce PR #91 --- src/router/router.rs | 53 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/router/router.rs b/src/router/router.rs index 6d10b12e35..6fec5ff108 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -75,10 +75,19 @@ impl<'a> Router { impl HttpRouter for Router { fn add_route(&mut self, method: Method, path: &str, handler: H) { - let matcher = path_utils::create_regex(path); - let variable_infos = path_utils::get_variable_info(path); + static FORMAT_VAR: &'static str = ":format"; + + let with_format = if path.contains(FORMAT_VAR) { + path.to_string() + } else { + format!("{}(\\.{})?", path, FORMAT_VAR) + }; + + let matcher = path_utils::create_regex(&with_format); + let variable_infos = path_utils::get_variable_info(&with_format); + let route = Route { - path: path.to_string(), + path: with_format, method: method, matcher: matcher, handler: Box::new(handler), @@ -180,15 +189,18 @@ fn can_match_var_routes () { route_store.add_route(Method::Get, "/foo/:userid", handler); route_store.add_route(Method::Get, "/bar", handler); + route_store.add_route(Method::Get, "/file/:format/:file", handler); let route_result = route_store.match_route(&Method::Get, "/foo/4711").unwrap(); let route = route_result.route; assert_eq!(route_result.param("userid"), "4711"); - //assert the route has identified the variable - assert_eq!(route.variables.len(), 1); + // assert the route has identified the variable + assert_eq!(route.variables.len(), 2); assert_eq!(route.variables["userid".to_string()], 0); + // routes have an implicit format variable + assert_eq!(route.variables["format".to_string()], 1); let route_result = route_store.match_route(&Method::Get, "/bar/4711"); assert!(route_result.is_none()); @@ -196,18 +208,45 @@ fn can_match_var_routes () { let route_result = route_store.match_route(&Method::Get, "/foo"); assert!(route_result.is_none()); - //ensure that this will work with commas too + // ensure that this will work with commas too let route_result = route_store.match_route(&Method::Get, "/foo/123,456"); assert!(route_result.is_some()); let route_result = route_result.unwrap(); assert_eq!(route_result.param("userid"), "123,456"); - //ensure that this will work with spacing too + // ensure that this will work with spacing too let route_result = route_store.match_route(&Method::Get, "/foo/John%20Doe"); assert!(route_result.is_some()); let route_result = route_result.unwrap(); assert_eq!(route_result.param("userid"), "John%20Doe"); + + // check for optional format param + let route_result = route_store.match_route(&Method::Get, "/foo/John%20Doe.json"); + assert!(route_result.is_some()); + + let route_result = route_result.unwrap(); + assert_eq!(route_result.param("userid"), "John%20Doe"); + assert_eq!(route_result.param("format"), ".json"); + + // ensure format works with queries + let route_result = route_store.match_route(&Method::Get, + "/foo/5490,1234.csv?foo=true&bar=false"); + assert!(route_result.is_some()); + + let route_result = route_result.unwrap(); + // NOTE: `.param` doesn't cover query params currently + assert_eq!(route_result.param("userid"), "5490,1234"); + assert_eq!(route_result.param("format"), ".csv"); + + // ensure format works if defined by user + let route_result = route_store.match_route(&Method::Get, "/file/markdown/something?foo=true"); + assert!(route_result.is_some()); + + let route_result = route_result.unwrap(); + // NOTE: `.param` doesn't cover query params currently + assert_eq!(route_result.param("file"), "something"); + assert_eq!(route_result.param("format"), "markdown"); }