use axum::{ http::{header, StatusCode}, response::{IntoResponse, Response}, }; use mime_guess::Mime; use rust_embed::EmbeddedFile; use crate::{error::Internal, ui::error::NotFound}; #[derive(rust_embed::Embed)] #[folder = "target/ui"] pub struct Assets; impl Assets { pub fn load(path: impl AsRef) -> Result> { let path = path.as_ref(); let mime = mime_guess::from_path(path).first_or_octet_stream(); Self::get(path) .map(|file| Asset(mime, file)) .ok_or(NotFound(format!("not found: {path}"))) } pub fn index() -> Result { // "not found" in this case really is an internal error, as it should // never happen. `index.html` is a known-valid path. Ok(Self::load("index.html")?) } } pub 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() } }