use super::*;
pub fn normalize_path(path: &str) -> String {
if path == "/" {
return "/".to_string();
}
path.trim_end_matches('/').to_string()
}
pub fn route_matches(route_path: &str, request_path: &str) -> bool {
let normalized_route: String = normalize_path(route_path);
let normalized_request: String = normalize_path(request_path);
if normalized_route == normalized_request {
return true;
}
if normalized_request.starts_with(&normalized_route)
&& normalized_request.chars().nth(normalized_route.len()) == Some('/')
{
return true;
}
if normalized_route == "/" && !normalized_request.is_empty() {
return true;
}
false
}
pub fn find_active_route<'a>(
path: &str,
routes: &'a [NestedRouteConfig],
) -> Option<&'a NestedRouteConfig> {
for route in routes.iter() {
let normalized: String = normalize_path(&route.path);
let normalized_request: String = normalize_path(path);
if normalized == normalized_request {
if !route.children.is_empty()
&& let Some(child_match) = find_active_route(path, &route.children)
{
return Some(child_match);
}
return Some(route);
}
}
for route in routes.iter() {
if route_matches(&route.path, path) && route.path != normalize_path(path) {
if !route.children.is_empty()
&& let Some(child_match) = find_active_route(path, &route.children)
{
return Some(child_match);
}
return Some(route);
}
}
None
}
pub fn route_chain<'a>(path: &str, routes: &'a [NestedRouteConfig]) -> Vec<&'a NestedRouteConfig> {
let mut chain: Vec<&'a NestedRouteConfig> = Vec::new();
build_chain(path, routes, &mut chain);
chain
}
pub(crate) fn build_chain<'a>(
path: &str,
routes: &'a [NestedRouteConfig],
chain: &mut Vec<&'a NestedRouteConfig>,
) -> bool {
for route in routes.iter() {
let normalized: String = normalize_path(&route.path);
let normalized_request: String = normalize_path(path);
if normalized == normalized_request {
chain.push(route);
if !route.children.is_empty() {
let _ = build_chain(path, &route.children, chain);
}
return true;
}
}
for route in routes.iter() {
if route_matches(&route.path, path) && route.path != normalize_path(path) {
chain.push(route);
if !route.children.is_empty() {
let _ = build_chain(path, &route.children, chain);
}
return true;
}
}
false
}