use axum::{
body::Body,
extract::Path,
http::{Response, StatusCode, header},
response::IntoResponse,
};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "ui/dist/"]
struct UiAssets;
pub async fn spa_index_handler() -> impl IntoResponse {
serve_asset("index.html")
}
pub async fn spa_asset_handler(Path(path): Path<String>) -> impl IntoResponse {
let path = path.trim_start_matches('/');
serve_asset(path)
}
fn serve_asset(path: &str) -> Response<Body> {
match UiAssets::get(path) {
Some(content) => {
let mime = mime_guess::from_path(path).first_or_octet_stream();
Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, mime.as_ref())
.body(Body::from(content.data.to_vec()))
.unwrap_or_else(|_| {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.expect("static response")
})
}
None => {
match UiAssets::get("index.html") {
Some(content) => Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "text/html")
.body(Body::from(content.data.to_vec()))
.unwrap_or_else(|_| {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.expect("static response")
}),
None => Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("not found"))
.expect("static 404"),
}
}
}
}