use super::{RouteInfo, RouteVerdict};
use crate::i18n::Locales;
use crate::path::*;
use crate::template::{Entity, EntityMap, Forever};
use std::collections::HashMap;
use sycamore::web::Html;
fn get_template_for_path<'a, G: Html>(
path: &str,
render_cfg: &HashMap<String, String>,
entities: &'a EntityMap<G>,
) -> (Option<&'a Forever<Entity<G>>>, bool) {
let mut was_incremental_match = false;
let mut entity_name = None;
if let Some(entity_root_path) = render_cfg.get(path) {
entity_name = Some(entity_root_path.to_string());
}
if entity_name.is_none() {
let path_segments: Vec<&str> = path.split('/').collect();
for (idx, _) in path_segments.iter().enumerate() {
let path_to_try = path_segments[0..(idx + 1)].join("/") + "/*";
if let Some(entity_root_path) = render_cfg.get(&path_to_try) {
was_incremental_match = true;
entity_name = Some(entity_root_path.to_string());
}
}
}
if let Some(entity_name) = entity_name {
(entities.get(&entity_name), was_incremental_match)
} else if render_cfg.contains_key("/*") {
(entities.get(""), true)
} else {
(None, was_incremental_match)
}
}
pub(crate) fn match_route<G: Html>(
path_slice: &[&str],
render_cfg: &HashMap<String, String>,
entities: &EntityMap<G>,
locales: &Locales,
) -> RouteVerdict {
let path_vec = path_slice.to_vec();
let path_joined = PathMaybeWithLocale(path_vec.join("/"));
if locales.using_i18n && !path_slice.is_empty() {
let locale = path_slice[0];
if locales.is_supported(locale) {
let path_without_locale = PathWithoutLocale(path_slice[1..].to_vec().join("/"));
let (entity, was_incremental_match) =
get_template_for_path(&path_without_locale, render_cfg, entities);
match entity {
Some(entity) => RouteVerdict::Found(RouteInfo {
locale: locale.to_string(),
path: path_without_locale,
entity_name: entity.get_path(),
was_incremental_match,
}),
None => RouteVerdict::NotFound {
locale: locale.to_string(),
},
}
} else {
let path_joined = PathWithoutLocale(path_joined.0);
RouteVerdict::LocaleDetection(path_joined)
}
} else if locales.using_i18n {
let path_joined = PathWithoutLocale(path_joined.0);
RouteVerdict::LocaleDetection(path_joined)
} else {
let path_joined = PathWithoutLocale(path_joined.0);
let (entity, was_incremental_match) =
get_template_for_path(&path_joined, render_cfg, entities);
match entity {
Some(entity) => RouteVerdict::Found(RouteInfo {
locale: locales.default.to_string(),
path: path_joined,
entity_name: entity.get_path(),
was_incremental_match,
}),
None => RouteVerdict::NotFound {
locale: "xx-XX".to_string(),
},
}
}
}