use std::future::Future;
use std::pin::Pin;
use axum::body::Body;
use axum::http::Request;
use axum::response::Response;
pub fn serve_embedded_assets<E: rust_embed::Embed + 'static>(
req: Request<Body>,
) -> Pin<Box<dyn Future<Output = Response> + Send>> {
Box::pin(async move {
use axum::http::{StatusCode, header};
use axum::response::IntoResponse;
let path = req.uri().path().trim_start_matches('/');
let path = if path.is_empty() { "index.html" } else { path };
if let Some(content) = E::get(path) {
let mime = mime_guess::from_path(path).first_or_octet_stream();
return ([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response();
}
let flat = format!("{}.html", path);
if let Some(content) = E::get(&flat) {
return ([(header::CONTENT_TYPE, "text/html")], content.data).into_response();
}
let nested = format!("{}/index.html", path);
if let Some(content) = E::get(&nested) {
return ([(header::CONTENT_TYPE, "text/html")], content.data).into_response();
}
let fallback = E::get("200.html").or_else(|| E::get("index.html"));
match fallback {
Some(content) => ([(header::CONTENT_TYPE, "text/html")], content.data).into_response(),
None => (StatusCode::NOT_FOUND, "not found").into_response(),
}
})
}