use std::fmt::Write as _;
use std::path::{Path, PathBuf};
pub fn dist(manifest: &Path) -> Result<PathBuf, String> {
let console = manifest.join("../../apps/liminal-console");
let (found, other) = if console.is_dir() {
(console.join("dist"), None)
} else {
(manifest.join("console-dist"), Some(console.join("dist")))
};
if found.join("index.html").is_file() {
return Ok(found);
}
let also = other.map_or_else(String::new, |other| format!(" nor {}", other.display()));
Err(format!(
"missing console dist: {}{also} holds no index.html; build it with: cd apps/liminal-console && bun run build",
found.display(),
))
}
pub fn table(dist: &Path) -> Result<(String, Vec<PathBuf>), Box<dyn std::error::Error>> {
let mut files = Vec::new();
collect(dist, &mut files)?;
files.sort();
let mut table = String::from("const EMBEDDED: &[(&str, &str, &[u8])] = &[\n");
for path in &files {
let relative = path
.strip_prefix(dist)?
.to_str()
.ok_or("console asset path is not Unicode")?
.replace('\\', "/");
let absolute = std::fs::canonicalize(path)?;
let absolute = absolute
.to_str()
.ok_or("console asset path is not Unicode")?;
writeln!(
table,
"({:?}, {:?}, include_bytes!({absolute:?})),",
format!("/{relative}"),
mime(path)
)?;
}
table.push_str("];\n");
Ok((table, files))
}
fn collect(root: &Path, files: &mut Vec<PathBuf>) -> std::io::Result<()> {
for entry in std::fs::read_dir(root)? {
let entry = entry?;
let kind = entry.file_type()?;
if kind.is_dir() {
collect(&entry.path(), files)?;
} else if kind.is_file() {
files.push(entry.path());
}
}
Ok(())
}
fn mime(path: &Path) -> &'static str {
match path.extension().and_then(std::ffi::OsStr::to_str) {
Some("html") => "text/html; charset=utf-8",
Some("js" | "mjs") => "text/javascript; charset=utf-8",
Some("css") => "text/css; charset=utf-8",
Some("json" | "map") => "application/json",
Some("wasm") => "application/wasm",
Some("svg") => "image/svg+xml",
Some("png") => "image/png",
Some("jpg" | "jpeg") => "image/jpeg",
Some("ico") => "image/x-icon",
Some("woff2") => "font/woff2",
Some("woff") => "font/woff",
Some("ttf") => "font/ttf",
Some("txt") => "text/plain; charset=utf-8",
_ => "application/octet-stream",
}
}