use super::*;
fn decode_anchor(encoded: &str) -> String {
if !encoded.as_bytes().contains(&b'%') {
return encoded.to_string();
}
match decode_uri_component(encoded) {
Ok(value) => value.as_string().unwrap_or_else(|| encoded.to_string()),
Err(_) => encoded.to_string(),
}
}
pub(crate) fn parse_route(raw: &str) -> (String, Option<String>) {
match raw.split_once('#') {
Some((path, anchor)) if !anchor.is_empty() => {
(path.to_string(), Some(decode_anchor(anchor)))
}
Some((path, _)) => (path.to_string(), None),
None => (raw.to_string(), None),
}
}
pub(crate) fn locale_of(route: &str) -> &'static DocsLocale {
let site: &DocsSite = &crate::generated::SITE;
site.locales
.iter()
.filter(|locale: &&DocsLocale| locale.prefix != "/")
.find(|locale: &&DocsLocale| route.starts_with(locale.prefix))
.or_else(|| site.locales.iter().find(|locale| locale.prefix == "/"))
.unwrap_or(&site.locales[0])
}
pub(crate) fn find_page(route: &str) -> Option<&'static DocsPage> {
let site: &DocsSite = &crate::generated::SITE;
site.pages
.iter()
.find(|page: &&DocsPage| page.route == route)
.or_else(|| {
if route.ends_with('/') || route.ends_with(ROUTE_HTML_SUFFIX) {
None
} else {
let with_slash: String = format!("{route}/");
site.pages
.iter()
.find(|page: &&DocsPage| page.route == with_slash)
}
})
}
pub(crate) fn scope_for(
items: &'static [EuvSidebarItem],
route: &str,
) -> Option<&'static [EuvSidebarItem]> {
for item in items {
if item.link == Some(route) {
return Some(items);
}
if let Some(found) = scope_for(item.children, route) {
if flatten_links(found).len() < 2 {
return Some(items);
}
return Some(found);
}
}
None
}
pub(crate) fn flatten_links(items: &'static [EuvSidebarItem]) -> Vec<&'static EuvSidebarItem> {
let mut out: Vec<&'static EuvSidebarItem> = Vec::new();
for item in items {
if item.children.is_empty() {
if item.link.is_some() {
out.push(item);
}
} else {
if item.link.is_some() {
out.push(item);
}
out.extend(flatten_links(item.children));
}
}
out
}
pub(crate) fn site_root() -> String {
let Some(window) = window() else {
return URL_PATH_ROOT.to_string();
};
let Ok(mut path) = window.location().pathname() else {
return URL_PATH_ROOT.to_string();
};
if !path.ends_with('/') {
path.push('/');
}
if !crate::generated::SITE_LOCALE_DIR.is_empty()
&& let Some(root) = path.strip_suffix(crate::generated::SITE_LOCALE_DIR)
{
return root.to_string();
}
path
}
pub(crate) fn redirect_foreign_route() -> bool {
let Some(window) = window() else {
return false;
};
let location: Location = window.location();
let Ok(hash) = location.hash() else {
return false;
};
let path: &str = hash.strip_prefix('#').unwrap_or(&hash);
for redirect in crate::generated::SITE_REDIRECTS {
let head: &str = redirect.from;
let boundary: bool = path == head
|| path
.strip_prefix(head)
.is_some_and(|rest: &str| rest.starts_with('/'));
if !boundary {
continue;
}
let bare: &str = &path[head.len()..];
let bare: &str = if bare.is_empty() { URL_PATH_ROOT } else { bare };
if redirect.to_dir.is_empty() {
let _: Result<(), JsValue> = location.set_hash(bare);
return false;
}
let url: String = format!("{}{}#{}", site_root(), redirect.to_dir, bare);
let _: Result<(), JsValue> = location.replace(&url);
return true;
}
false
}