use axum::http::{StatusCode, Uri, header};
use axum::response::{IntoResponse, Response};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "frontend/dist/"]
pub struct Assets;
pub async fn serve_static(uri: Uri) -> Response {
let path = uri.path().trim_start_matches('/');
let file_path = if path.is_empty() { "index.html" } else { path };
match Assets::get(file_path) {
Some(content) => {
let content_type = content_type_from_path(file_path);
([(header::CONTENT_TYPE, content_type)], content.data).into_response()
}
None => {
if let Some(index) = Assets::get("index.html") {
([(header::CONTENT_TYPE, "text/html")], index.data).into_response()
} else {
(StatusCode::NOT_FOUND, "404 Not Found").into_response()
}
}
}
}
fn content_type_from_path(path: &str) -> &'static str {
let ext = path.rsplit('.').next().unwrap_or("");
match ext {
"html" => "text/html; charset=utf-8",
"css" => "text/css; charset=utf-8",
"js" => "application/javascript; charset=utf-8",
"mjs" => "application/javascript; charset=utf-8",
"json" => "application/json",
"png" => "image/png",
"jpg" | "jpeg" => "image/jpeg",
"svg" => "image/svg+xml",
"ico" => "image/x-icon",
"wasm" => "application/wasm",
"woff" => "font/woff",
"woff2" => "font/woff2",
"ttf" => "font/ttf",
_ => "application/octet-stream",
}
}