use camino::Utf8Component;
use camino::{Utf8Path, Utf8PathBuf};
pub fn to_slug(path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
let path = path.as_ref().with_extension("");
if let Some("index") = path.file_name() {
if let Some(parent) = path.parent() {
return parent.to_path_buf();
}
}
path.to_path_buf()
}
pub fn normalize_path(path: &Utf8Path) -> Utf8PathBuf {
let mut components = path.components().peekable();
let mut ret = if let Some(c @ Utf8Component::Prefix(..)) = components.peek().cloned() {
components.next();
Utf8PathBuf::from(c.as_str())
} else {
Utf8PathBuf::new()
};
for component in components {
match component {
Utf8Component::Prefix(..) => unreachable!(),
Utf8Component::RootDir => {
ret.push(Utf8Component::RootDir);
}
Utf8Component::CurDir => {}
Utf8Component::ParentDir => {
if ret.ends_with(Utf8Component::ParentDir) {
ret.push(Utf8Component::ParentDir);
} else {
let popped = ret.pop();
if !popped && !ret.has_root() {
ret.push(Utf8Component::ParentDir);
}
}
}
Utf8Component::Normal(c) => {
ret.push(c);
}
}
}
ret
}
pub fn normalize_prefixed(prefix: &str, path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
let path = path.as_ref().strip_prefix(prefix).unwrap_or(path.as_ref());
normalize(path)
}
pub fn normalize(path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
let mut buffer = path.as_ref().to_path_buf();
if let Some(file_name) = buffer.file_name() {
if file_name == "index" || file_name.starts_with("index.") {
buffer.set_extension("html");
} else {
buffer.set_extension("");
buffer.push("index.html");
}
} else {
buffer.push("index.html");
}
buffer
}
pub fn absolutize(prefix: &str, path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
let path = path.as_ref().strip_prefix(prefix).unwrap_or(path.as_ref());
let path = Utf8Path::new("/").join(path);
if let Some(file_name) = path.file_name() {
if file_name == "index" || file_name.starts_with("index.") {
path.parent().unwrap().to_path_buf()
} else {
path.with_extension("")
}
} else {
path
}
}
#[derive(Debug, Clone)]
pub struct Output {
pub url: Utf8PathBuf,
pub content: String,
}
impl Output {
pub fn html(path: impl AsRef<Utf8Path>, content: impl Into<String>) -> Self {
Self {
url: normalize(path),
content: content.into(),
}
}
pub fn file(path: impl Into<Utf8PathBuf>, content: impl Into<String>) -> Self {
Self {
url: path.into(),
content: content.into(),
}
}
}
use std::fs;
use std::io;
use std::path::Path;
pub(crate) fn save_pages_to_dist(pages: &[Output]) -> io::Result<()> {
let output_dir = Path::new("dist");
fs::create_dir_all(output_dir)?;
for page in pages {
let file_path = output_dir.join(&page.url);
if let Some(parent_dir) = file_path.parent() {
fs::create_dir_all(parent_dir)?;
}
fs::write(&file_path, &page.content)?;
}
Ok(())
}