From 214a9e6c1fd729fc2c49eb2a5d41b5651ff5bc61 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 22 Oct 2024 22:12:56 -0400 Subject: Set `charset` params on returned content types. This is a somewhat indirect change; it removes `mime_guess` in favour of some very, uh, "bespoke" mime detection logic that hardcodes mime types for the small repertoire of file extensions actually present in the UI. `mime_guess` doesn't provide a way to set params as it exports its own `Mime` struct, which doesn't provide `with_params()`. --- src/ui/assets.rs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/ui/assets.rs') diff --git a/src/ui/assets.rs b/src/ui/assets.rs index 342ba59..6a7563a 100644 --- a/src/ui/assets.rs +++ b/src/ui/assets.rs @@ -1,29 +1,31 @@ +use ::mime::{FromStrError, Mime}; use axum::{ http::{header, StatusCode}, response::{IntoResponse, Response}, }; -use mime_guess::Mime; use rust_embed::EmbeddedFile; -use crate::{error::Internal, ui::error::NotFound}; +use super::{error::NotFound, mime}; +use crate::error::Internal; #[derive(rust_embed::Embed)] #[folder = "target/ui"] pub struct Assets; impl Assets { - pub fn load(path: impl AsRef) -> Result> { + pub fn load(path: impl AsRef) -> Result { let path = path.as_ref(); - let mime = mime_guess::from_path(path).first_or_octet_stream(); + let mime = mime::from_path(path)?; Self::get(path) .map(|file| Asset(mime, file)) - .ok_or(NotFound(format!("not found: {path}"))) + .ok_or(Error::NotFound(path.into())) } 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. + // never happen. `index.html` is a known-valid path with a known-valid + // file extension. Ok(Self::load("index.html")?) } } @@ -41,3 +43,21 @@ impl IntoResponse for Asset { .into_response() } } + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("not found: {0}")] + NotFound(String), + #[error(transparent)] + Mime(#[from] FromStrError), +} + +impl IntoResponse for Error { + fn into_response(self) -> Response { + #[allow(clippy::match_wildcard_for_single_variants)] + match self { + Self::NotFound(_) => NotFound(self.to_string()).into_response(), + other => Internal::from(other).into_response(), + } + } +} -- cgit v1.2.3