use axum::http::{Uri, header};
use axum::response::{IntoResponse, Response};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "web/dist/"]
struct Assets;
pub(crate) async fn static_handler(uri: Uri) -> Response {
let path = uri.path().trim_start_matches('/');
let path = if path.is_empty() { "index.html" } else { path };
match Assets::get(path) {
Some(content) => ([(header::CONTENT_TYPE, mime_for(path))], content.data).into_response(),
None => match Assets::get("index.html") {
Some(index) => ([(header::CONTENT_TYPE, "text/html")], index.data).into_response(),
None => (
[(header::CONTENT_TYPE, "text/html; charset=utf-8")],
FALLBACK_HTML,
)
.into_response(),
},
}
}
const FALLBACK_HTML: &str = "<!doctype html><meta charset=utf-8><title>bambu dashboard</title>\
<body style=\"font-family:system-ui;padding:2rem\"><h1>bambu dashboard</h1>\
<p>The web UI isn't built yet. Run <code>pnpm -C web build</code> (or use a release \
binary). The API at <code>/api/*</code> is available.</p></body>";
fn mime_for(path: &str) -> &'static str {
match path.rsplit('.').next() {
Some("html") => "text/html; charset=utf-8",
Some("js" | "mjs") => "text/javascript",
Some("css") => "text/css",
Some("json") => "application/json",
Some("svg") => "image/svg+xml",
Some("png") => "image/png",
Some("ico") => "image/x-icon",
Some("woff2") => "font/woff2",
_ => "application/octet-stream",
}
}