use std::ffi::OsStr;
use std::path::{Path, PathBuf};
const DIRECTORY_INDEX: &str = "index.html";
const INDEX_STEM: &str = "index";
const HTML_EXTENSION: &str = "html";
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct Route {
pub(crate) output_relative: PathBuf,
pub(crate) url_relative: String,
}
pub(crate) fn route(relative_md: &Path, pretty_urls: bool) -> Route {
let stem = relative_md.with_extension("");
let url_stem = to_url_path(&stem);
if !pretty_urls {
return Route {
output_relative: relative_md.with_extension(HTML_EXTENSION),
url_relative: format!("{url_stem}.{HTML_EXTENSION}"),
};
}
if relative_md.file_stem() == Some(OsStr::new(INDEX_STEM)) {
return Route {
output_relative: relative_md.with_extension(HTML_EXTENSION),
url_relative: drop_last_segment(&url_stem),
};
}
Route {
output_relative: stem.join(DIRECTORY_INDEX),
url_relative: url_stem,
}
}
pub(crate) fn route_link(dest_no_extension: &str, pretty_urls: bool) -> String {
if !pretty_urls {
return format!("{dest_no_extension}.{HTML_EXTENSION}");
}
if last_segment(dest_no_extension) == INDEX_STEM {
return drop_last_segment(dest_no_extension);
}
dest_no_extension.to_string()
}
fn to_url_path(path: &Path) -> String {
path.to_string_lossy().replace('\\', "/")
}
fn last_segment(url_path: &str) -> &str {
url_path.rsplit('/').next().unwrap_or(url_path)
}
fn drop_last_segment(url_path: &str) -> String {
match url_path.rsplit_once('/') {
Some((parent, _)) => parent.to_string(),
None => String::new(),
}
}
#[cfg(test)]
#[path = "../tests/unit/route.rs"]
mod tests;