use axum::http::{header, StatusCode, Uri};
use axum::response::{IntoResponse, Response};
use rust_embed::Embed;
#[derive(Embed)]
#[folder = "../../web/dist"]
struct Assets;
pub async fn serve_spa(uri: Uri) -> Response {
let path = uri.path().trim_start_matches('/');
if !path.is_empty() {
if let Some(asset) = Assets::get(path) {
let mime = mime_guess::from_path(path).first_or_octet_stream();
return (
StatusCode::OK,
[
(header::CONTENT_TYPE, mime.as_ref().to_string()),
(
header::CACHE_CONTROL,
"public, max-age=31536000, immutable".to_string(),
),
],
asset.data.to_vec(),
)
.into_response();
}
}
if !path.is_empty() && path.contains('.') {
return (StatusCode::NOT_FOUND, "Not found").into_response();
}
match Assets::get("index.html") {
Some(asset) => (
StatusCode::OK,
[
(header::CONTENT_TYPE, "text/html".to_string()),
(header::CACHE_CONTROL, "no-cache".to_string()),
],
asset.data.to_vec(),
)
.into_response(),
None => (
StatusCode::NOT_FOUND,
"Web companion not built. Run: cd web && npm run build",
)
.into_response(),
}
}