use axum::{ extract::Path, http::{header, StatusCode}, response::{IntoResponse, Response}, routing::get, Router, }; use mime_guess::Mime; use rust_embed::EmbeddedFile; #[derive(rust_embed::Embed)] #[folder = "hi-ui/build"] struct Assets; pub fn router() -> Router where S: Clone + Send + Sync + 'static, { Router::new() .route("/*path", get(asset)) .route("/", get(root)) } async fn asset(Path(path): Path) -> Result> { let mime = mime_guess::from_path(&path).first_or_octet_stream(); Assets::get(&path) .map(|file| Asset(mime, file)) .ok_or(NotFound(format!("not found: {path}"))) } async fn root() -> impl IntoResponse { asset(Path(String::from("index.html"))).await } struct Asset(Mime, EmbeddedFile); impl IntoResponse for Asset { fn into_response(self) -> Response { let Self(mime, file) = self; ( StatusCode::OK, [(header::CONTENT_TYPE, mime.as_ref())], file.data, ) .into_response() } } struct NotFound(pub E); impl IntoResponse for NotFound where E: IntoResponse, { fn into_response(self) -> Response { let Self(response) = self; (StatusCode::NOT_FOUND, response).into_response() } }