diff options
Diffstat (limited to 'src/ui/assets.rs')
| -rw-r--r-- | src/ui/assets.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/ui/assets.rs b/src/ui/assets.rs new file mode 100644 index 0000000..342ba59 --- /dev/null +++ b/src/ui/assets.rs @@ -0,0 +1,43 @@ +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<str>) -> Result<Asset, NotFound<String>> { + 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<Asset, Internal> { + // "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() + } +} |
