use axum::{
http::{header, StatusCode, Uri},
response::{IntoResponse, Response},
};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "web/"]
struct WebAssets;
fn serve_file(path: &str) -> Response {
const NO_CACHE: &str = "no-store, must-revalidate";
match WebAssets::get(path) {
Some(content) => {
let mime = mime_guess::from_path(path).first_or_octet_stream();
(
[
(header::CONTENT_TYPE, mime.as_ref()),
(header::CACHE_CONTROL, NO_CACHE),
],
content.data.into_owned(),
)
.into_response()
}
None => {
match WebAssets::get("index.html") {
Some(content) => (
[
(header::CONTENT_TYPE, "text/html; charset=utf-8"),
(header::CACHE_CONTROL, NO_CACHE),
],
content.data.into_owned(),
)
.into_response(),
None => (StatusCode::NOT_FOUND, "not found").into_response(),
}
}
}
}
pub async fn fallback(uri: Uri) -> Response {
let path = uri.path();
if let Some(rest) = path.strip_prefix("/admin") {
let rest = rest.trim_start_matches('/');
let file = if rest.is_empty() { "index.html" } else { rest };
serve_file(file)
} else {
(
StatusCode::NOT_FOUND,
axum::Json(serde_json::json!({
"error": { "message": "not found", "type": "not_found", "code": "not_found" }
})),
)
.into_response()
}
}